Cakephp : display data in a table with other table's data

孤街浪徒 提交于 2019-12-12 03:56:29

问题


I'm displaying my users in a table, and I am retrieving the company name and city with company_id

users :

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

companies :

id  name                city
1   New-York Company    New-York
2   Paris Company       Paris

user display :

            <?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',
    ]);
}

}       

?>

So in my company display, I would like to retrieve admin and author names, like so :

                <?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;?>     

I have tried getting company id to reference company_id in users for starters to get on track, without success(trying to get property of non-object)

Furthermore, would it work if I have several authors and admins ? Less likely to several admins per companies, but can happen, and several authors is definetely possible

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;


}




 }

Edit : adding Companies/index.ctp, still too new, I do not see at all what's wrong... :

<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>

I am getting these errors :

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]

which corresponds to this :

 <?php foreach ($company->users as $user):?> 

CompaniesController :

 <?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);
    }
 }

thanks in advance


回答1:


First things first, you cannot define multiple associations with the same name. Given that you have a company_id field, that is a belongsTo association from the users point of view.

Given these prerequisites, it's naturally a hasMany association from the companies point of view. I assume that you've set that up already in your CompaniesTable class, if not, then that's what you need to do first.

The users property will then be an array of User entitiy objects, so you need to access it accordingly, that is either directly via an index:

$company->users[0]->firstname

or by iterating over it:

foreach ($company->users as $user) {
    // $user->firstname
}

If you need to handle the users separated by their roles, then you could for example filter them accordingly:

$admins = collection($company->users)->filter(function ($user) {
    return $user->role === 'admin';
});

or maybe better yet create separate associations using conditions:

$this->hasMany('Admins', [
    'className' => 'Users',
    'conditions' => [
        'Admins.role' => 'admin'
    ]
]);

$this->hasMany('Authors', [
    'className' => 'Users',
    'conditions' => [
        'Admins.role' => 'author'
    ]
]);

That way you could contain and access the different types of users separately:

$company->admins
$company->authors

See also

  • Cookbook > Database Access & ORM > Associations - Linking Tables Together
  • Cookbook > Database Access & ORM > Retrieving Data & Results Sets > Eager Loading Associations Via Contain


来源:https://stackoverflow.com/questions/44702787/cakephp-display-data-in-a-table-with-other-tables-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!