Reputation: 33
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
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