Cakephp: отображать данные в таблице вместе с данными другой таблицы
Я отображаю своих пользователей в таблице и извлекаю название компании и город с помощью company_id
пользователи:
id lastname firstname company_id role
1 doe john 2 author
2 deo jenne 2 admin
3 deus Joe 1 admin
4 Stewart Rob 1 author
компании:
id name city
1 New-York Company New-York
2 Paris Company Paris
пользовательский дисплей:
<?php
foreach($users as $user):?>
<tr>
<td><?= $user->lastname?></td>
<td><?= $user->firstname?></td>
<td><?= $user->companies->name ?></td>
<td><?= $user->companies->city?></td>
<td><?= $user->role?></td>
</tr>
<?php endforeach;?>
usersTable.php:
<?php
namespace App\Model\Table;
use Cake\ORM\Table;
use Cake\Validation\Validator;
class UsersTable extends Table
{
public function initialize(array $config){
$this->belongsToMany('Companies');
$this->belongsTo('Companies', [
'foreignKey' => 'company_id',
]);
}
}
?>
Так что на дисплее моей компании я хотел бы получить имена администраторов и авторов, например:
<?php
foreach($companies as $company):?>
<tr>
<td><?= $company->name?></td>
<td><?= $company->city?></td>
<td><?= $company->users-> *adminlastname* ?></td>
<td><?= $company->users-> *adminfirstname* ?></td>
<td><?= $company->users-> *authorlastname* ?></td>
<td><?= $company->users-> *authorfirstname* ?></td>
</tr>
<?php endforeach;?>
Я пытался получить идентификатор компании для ссылки на company_id в пользователях, для начала, чтобы идти в нужном направлении, но безуспешно (пытаясь получить свойство не-объекта)
Кроме того, будет ли это работать, если у меня есть несколько авторов и администраторов? Менее вероятно для нескольких администраторов на компании, но может случиться, и несколько авторов определенно возможно
companiesTable:
<?php
namespace App\Model\Table;
use Cake\ORM\Table;
use Cake\Validation\Validator;
class companiesTable extends Table
{
public function initialize(array $config){
//$this->addBehavior('Timestamp');
$this->hasMany('Users');
$this->hasMany('companies', [
'foreignKey' => 'identite',
]);
$this->hasMany('Admins', [
'className' => 'Users',
'conditions' => [
'Admins.role' => 'admin'
]
]);
$this->hasMany('Authors', [
'className' => 'Users',
'conditions' => [
'Admins.role' => 'author'
]
]);
}
public function isOwnedBy($companyId, $userId){
$company = $this
->find('all',['conditions' => ['companies.id'=>$companyId]])
->matching('Users', function ($q) use ($userId) {
return $q->where(['Users.id' => $userId]);
})
->first();
if ($company) return true;
return false;
}
}
Редактировать: добавление Companies/index.ctp, все еще слишком новое, я не вижу, что не так...:
<div class="row">
<div class="medium-4 small-12 columns">
<div style="padding: 22px;">
<h2>companies</h2>
</div>
<div id="customAdd" style="clear:both;padding: 22px;">
<a href="/companies/add" class="button secondary right" data-reveal-id="Modal" data-reveal-ajax="true">add</a>
<div style="clear:both;height:0px;"></div>
</div>
<div id="customSearch" style="clear: both;padding: 22px">
<p style="font-size:36px; display: inline-block;">search for a company</p><input type="text" id="searchBox">
</div>
</div>
<div class="medium-8 small-12 columns">
<div>
<table id="companies" class="cell-border dataTable no-footer">
<thead>
<tr>
<th>name</th>
<th>city</th>
<th>last name</th>
<th>first name</th>
</tr>
</thead>
<tbody>
<?php foreach ($company->users as $user):?>
<tr class='clickable-row' data-href="/companies/edit/<?= $company->id?>">
<td><?= $company->name?></td>
<td><?= $company->city?></td>
<td><?= $company->users[0]->lastname?></td>
<td><?= $company->users[0]->firstname?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
</div>
</div>
Я получаю эти ошибки:
Notice (8): Undefined variable: company [APP/Template/Companies/index.ctp, line 36]
Notice (8): Trying to get property of non-object [APP/Template/Companies/index.ctp, line 36]
Warning (2): Invalid argument supplied for foreach() [APP/Template/Companies/index.ctp, line 36]
что соответствует этому:
<?php foreach ($company->users as $user):?>
КомпанииКонтроллер:
<?php
namespace App\Controller;
use Cake\ORM\TableRegistry;
class CompaniesController extends AppController{
public function index(){
$companies = $this->Companies
->find('all',['order' => ['Companies.name' => 'ASC']]);
$this->set(compact('companies'));
$this->loadModel('Users');
$users = $this->Users->find('all')
->contain(['companies']);
$this->set(compact('users'));
}
public function view($id = null){
$company = $this->Companies->get($id);
$this->set(compact('company'));
}
public function add(){
$company = $this->Companies->newEntity();
if ($this->request->is('post')) {
if ($this->Companies->save($company)) {
$this->Flash->success(__('Your company has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Unable to add your company.'));
}
$this->set('company', $company);
$this->set(compact('companies'));
}
public function edit($id = null){
$company = $this->Companies->get($id);
if ($this->request->is(['post', 'put'])) {
$company = $this->Companies->patchEntity($company, $this->request->data,['associated' => ['Users']]);
if ($this->Companies->save($company)) {
$this->Flash->success(__('Your company has been updated.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Unable to update your company.'));
}
$this->set('company', $company);
$this->set(compact('companies'));
}
public function delete($id){
$this->request->allowMethod(['post', 'delete']);
$company = $this->Companies->get($id);
if ($this->Companies->delete($company)) {
$this->Flash->success(__('The company with id: {0} has been deleted.', h($id)));
return $this->redirect(['action' => 'index']);
}
}
public function isAuthorized($user){
if ($this->request->action === 'logout') {
return true;
}
if ($this->request->action === 'settings') {
return true;
}
return parent::isAuthorized($user);
}
}
заранее спасибо
1 ответ
Прежде всего, вы не можете определить несколько ассоциаций с одним и тем же именем. Учитывая, что у вас есть company_id
поле, то есть belongsTo
ассоциация с точки зрения пользователей.
Учитывая эти предпосылки, это естественно hasMany
ассоциация с точки зрения компаний. Я предполагаю, что вы уже настроили это в своем CompaniesTable
класс, если нет, то это то, что вам нужно сделать в первую очередь.
users
свойство будет массивом User
Права доступа к объектам, поэтому вам необходимо получить к ним соответствующий доступ, то есть напрямую через индекс:
$company->users[0]->firstname
или перебирая его:
foreach ($company->users as $user) {
// $user->firstname
}
Если вам нужно обрабатывать пользователей, разделенных их ролями, вы можете, например, отфильтровать их соответствующим образом:
$admins = collection($company->users)->filter(function ($user) {
return $user->role === 'admin';
});
или, может быть, лучше создать отдельные ассоциации, используя условия:
$this->hasMany('Admins', [
'className' => 'Users',
'conditions' => [
'Admins.role' => 'admin'
]
]);
$this->hasMany('Authors', [
'className' => 'Users',
'conditions' => [
'Admins.role' => 'author'
]
]);
Таким образом, вы можете содержать и получать доступ к различным типам пользователей отдельно:
$company->admins
$company->authors
Смотрите также