Spippo
Spippo

Reputation: 33

Can't get cakephp 3.0 association working

I've been working with cakephp 2.x for some time, and now started a new project on cakephp 3.0. But I can't get the association working for my users/roles tables. I went through the cakephp documentation, and searched google a lot for answers, but nothing.

Any help?

MySQL 'users' table:

id        int(11)        unsigned    NOT NULL    AUTO_INCREMENT    PRIMARY KEY
username  varchar(32)                NOT NULL
email     varchar(64)                NOT NULL
password  varchar(255)               NOT NULL
role_id   int(11)        unsigned    NOT NULL
active    tinyint(1)     unsigned    NOT NULL
created   datetime                   NULL
modified  datatime                   NULL

MySQL 'roles' table:

id        int(11)        unsigned    NOT NULL    AUTO_INCREMENT     PRIMARY KEY
name      varchar(64)                NOT NULL
level     int(11)                    0
created   datetime                   NULL
modified  datetime                   NULL

/src/Model/Entitiy/Role.php

<?php
namespace App\Model\Entity;

use Cake\ORM\Entity;

class Role extends Entity
{
     protected $_accessible = [
          'name' => true,
          'level' => true,
     ];
}

/src/Model/Entity/User.php

<?php
namespace App\Model\Entity;

use Cake\ORM\Entity;
user Cake\Auth\DefaultPasswordHasher;

class Userextends Entity
{
     protected $_accessible = [
          'username' => true,
          'email' => true,
          'password' => true,
          'role_id' => true,
     ];

     protected function _setPassword($value)
     {
          return (new DefaultPasswordHasher)->hash($value);
     }
}

src/Model/Table/UsersTable.php

<?php
namespace App\Model\Table;

use App\Model\Entity\User;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;

class UsersTable extends Table
{
    public function initialize(array $config)
    {
        $this->table('users');
        $this->displayField('username');
        $this->primaryKey('id');

        $this->belongsTo('Roles');
    }

    public function validationDefault(Validator $validator)
    {
        $validator
            ->add('id', 'valid', ['rule' => 'numeric'])
            ->allowEmpty('id', 'create');

        $validator
            ->requirePresence('username', 'create')
            ->notEmpty('username');

        $validator
            ->add('email', 'valid', ['rule' => 'email'])
            ->requirePresence('email', 'create')
            ->notEmpty('email');

        $validator
            ->requirePresence('password', 'create')
            ->notEmpty('password');

        return $validator;
    }

    public function buildRules(RulesChecker $rules)
    {
        $rules->add($rules->isUnique(['username']));
        $rules->add($rules->isUnique(['email']));
        return $rules;
    }
}

src/Model/Table/RolesTable.php

<?php
namespace App\Model\Table;

use App\Model\Entity\Role;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;

class RolesTable extends Table
{
    public function initialize(array $config)
    {
        $this->table('roles');
        $this->displayField('name');
        $this->primaryKey('id');
        $this->hasMany('Users');
    }

    public function validationDefault(Validator $validator)
    {
        $validator
            ->add('id', 'valid', ['rule' => 'numeric'])
            ->allowEmpty('id', 'create');

        $validator
            ->requirePresence('name', 'create')
            ->notEmpty('name');

        $validator
            ->add('level', 'valid', ['rule' => 'numeric'])
            ->requirePresence('level', 'create')
            ->notEmpty('level');

    return $validator;
    }

    public function buildRules(RulesChecker $rules)
    {
        $rules->add($rules->isUnique(['name']));
        $rules->add($rules->isUnique(['level']));
        return $rules;
    }
}

I did a quick check (I know, not best practice to put echo or print_r in a controller, but it's just a check) to print the first user.

src/Controller/UsersController.php

<?php

namespace App\Controller;

use App\Controller\AppController;
use Cake\Event\Event;

class UsersController extends AppController
{

    public function index()
    {
        // In a controller or table method.
        echo '<pre>';
        $query = $this->Users->findById(1);
        foreach ($query as $user) 
        {
             print_r($user->toArray());
        }
        echo '</pre>';
    }

    ...
}

But when I open the 'users' page, it just shows me the information of the user class, with a 'role_id'. But not the role details.

Array
(
    [id] => 1
    [username] => Test
    [email] => [email protected]
    [password] => ***
    [role_id] => 1
    [active] => 1
    [created] => Cake\I18n\Time Object
        (
            [date] => 2015-06-29 12:43:39.000000
            [timezone_type] => 3
            [timezone] => UTC
        )

    [modified] => Cake\I18n\Time Object
        (
            [date] => 2015-06-29 12:43:39.000000
            [timezone_type] => 3
        [timezone] => UTC
        )
)

Upvotes: 0

Views: 439

Answers (1)

Jack
Jack

Reputation: 79

I think the problem is that the 3.0 cakePHP does not automatically perform eager loading... try changing your find to use the new second argument and specify it as:

$this->get(1, ['contain' => ['Roles']]);

or use

$this->find('all')
     ->where('User.id' => 1)
     ->contain('Roles');

Upvotes: 1

Related Questions