我怎样才能在 cakephp 中正确关联这些表?
How can I correctly relate these tables in cakephp?
我正在尝试使用 cakephp3 创建一组 CRUD。我的数据库模型如下所示:
我使用 cake 的身份验证教程创建了用户 table,class 是的,它工作正常。但我想使用一组更复杂的角色,所以我创建了这些其他 tables。创建数据库模型后,我烘焙了相应的 classes,进行了一些调整并让系统和角色 CRUD 正常工作。现在我想集成 roles_users table,可能在用户的 CRUD 内部。
我想在自己编写此关系之前先看看 cake's bake 是怎么做的,但我无法打开 /rolesUsers。当我调用 URL 时,我收到以下错误消息:
Cannot match provided foreignKey for "Roles", got "(role_id)" but expected foreign key for "(id, system_id)" RuntimeException
我认为这是因为 system_id 是角色 table 中的 PK 而在 roles_users 中不存在(我将展示烘焙模型并且此 PK 将存在在角色 class)。 有没有一种简单的方法可以在不在 roles_users 中添加 system_id 的情况下使其工作? IMO 添加这个额外的字段不会是一个大问题,但我想知道我是否做错了什么,一些糟糕的设计决定。
我的src/Model/Table/RolesUsersTable.php:
<?php
namespace App\Model\Table;
use App\Model\Entity\RolesUser;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
/**
* RolesUsers Model
*
* @property \Cake\ORM\Association\BelongsTo $Users
* @property \Cake\ORM\Association\BelongsTo $Roles
*/
class RolesUsersTable extends Table
{
/**
* Initialize method
*
* @param array $config The configuration for the Table.
* @return void
*/
public function initialize(array $config)
{
parent::initialize($config);
$this->table('roles_users');
$this->displayField('user_id');
$this->primaryKey(['user_id', 'role_id']);
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
'joinType' => 'INNER'
]);
$this->belongsTo('Roles', [
'foreignKey' => 'role_id',
'joinType' => 'INNER'
]);
}
/**
* Default validation rules.
*
* @param \Cake\Validation\Validator $validator Validator instance.
* @return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator)
{
$validator
->add('valido_ate', 'valid', ['rule' => 'date'])
->requirePresence('valido_ate', 'create')
->notEmpty('valido_ate');
return $validator;
}
/**
* Returns a rules checker object that will be used for validating
* application integrity.
*
* @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
* @return \Cake\ORM\RulesChecker
*/
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->existsIn(['user_id'], 'Users'));
$rules->add($rules->existsIn(['role_id'], 'Roles'));
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;
/**
* Roles Model
*
* @property \Cake\ORM\Association\BelongsTo $Systems
*/
class RolesTable extends Table
{
/**
* Initialize method
*
* @param array $config The configuration for the Table.
* @return void
*/
public function initialize(array $config)
{
parent::initialize($config);
$this->table('roles');
$this->displayField('name');
$this->primaryKey(['id', 'system_id']);
$this->belongsTo('Systems', [
'foreignKey' => 'system_id',
'joinType' => 'INNER'
]);
}
/**
* Default validation rules.
*
* @param \Cake\Validation\Validator $validator Validator instance.
* @return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator)
{
$validator
->add('id', 'valid', ['rule' => 'numeric'])
->allowEmpty('id', 'create');
$validator
->requirePresence('name', 'create')
->notEmpty('name');
$validator
->add('status', 'valid', ['rule' => 'numeric'])
->requirePresence('status', 'create')
->notEmpty('status');
return $validator;
}
/**
* Returns a rules checker object that will be used for validating
* application integrity.
*
* @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
* @return \Cake\ORM\RulesChecker
*/
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->existsIn(['system_id'], 'Systems'));
return $rules;
}
}
我的src/Model/Table/UsersTable:
<?php
namespace App\Model\Table;
use Cake\ORM\Table;
use Cake\Validation\Validator;
class UsersTable extends Table{
public function validationDefault(Validator $validator){
return $validator
->notEmpty('username', 'O campo nome de usuário é obrigatório')
->notEmpty('password', 'O campo senha é obrigatório')
->notEmpty('role', 'O campo perfil é obrigatório')
->add('role', 'inList', [
'rule' => ['inList', ['admin', 'author']],
'message' => 'Escolha um perfil válido'
]
);
}
}
?>
用户 jose_zap 在 #cakephp @freenode 中回答:
在 RolesUsersTable.php 初始化函数中,我为 $this->belongsTo 调用添加了一个参数,包括 'bindingKey' 和值 'id'。所以这个旧代码:
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
'joinType' => 'INNER'
]);
$this->belongsTo('Roles', [
'foreignKey' => 'role_id',
'joinType' => 'INNER'
]);
变成了这个:
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
'bindingKey' => 'id',
'joinType' => 'INNER'
]);
$this->belongsTo('Roles', [
'foreignKey' => 'role_id',
'bindingKey' => 'id',
'joinType' => 'INNER'
]);
我正在尝试使用 cakephp3 创建一组 CRUD。我的数据库模型如下所示:
我使用 cake 的身份验证教程创建了用户 table,class 是的,它工作正常。但我想使用一组更复杂的角色,所以我创建了这些其他 tables。创建数据库模型后,我烘焙了相应的 classes,进行了一些调整并让系统和角色 CRUD 正常工作。现在我想集成 roles_users table,可能在用户的 CRUD 内部。
我想在自己编写此关系之前先看看 cake's bake 是怎么做的,但我无法打开 /rolesUsers。当我调用 URL 时,我收到以下错误消息:
Cannot match provided foreignKey for "Roles", got "(role_id)" but expected foreign key for "(id, system_id)" RuntimeException
我认为这是因为 system_id 是角色 table 中的 PK 而在 roles_users 中不存在(我将展示烘焙模型并且此 PK 将存在在角色 class)。 有没有一种简单的方法可以在不在 roles_users 中添加 system_id 的情况下使其工作? IMO 添加这个额外的字段不会是一个大问题,但我想知道我是否做错了什么,一些糟糕的设计决定。
我的src/Model/Table/RolesUsersTable.php:
<?php
namespace App\Model\Table;
use App\Model\Entity\RolesUser;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
/**
* RolesUsers Model
*
* @property \Cake\ORM\Association\BelongsTo $Users
* @property \Cake\ORM\Association\BelongsTo $Roles
*/
class RolesUsersTable extends Table
{
/**
* Initialize method
*
* @param array $config The configuration for the Table.
* @return void
*/
public function initialize(array $config)
{
parent::initialize($config);
$this->table('roles_users');
$this->displayField('user_id');
$this->primaryKey(['user_id', 'role_id']);
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
'joinType' => 'INNER'
]);
$this->belongsTo('Roles', [
'foreignKey' => 'role_id',
'joinType' => 'INNER'
]);
}
/**
* Default validation rules.
*
* @param \Cake\Validation\Validator $validator Validator instance.
* @return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator)
{
$validator
->add('valido_ate', 'valid', ['rule' => 'date'])
->requirePresence('valido_ate', 'create')
->notEmpty('valido_ate');
return $validator;
}
/**
* Returns a rules checker object that will be used for validating
* application integrity.
*
* @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
* @return \Cake\ORM\RulesChecker
*/
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->existsIn(['user_id'], 'Users'));
$rules->add($rules->existsIn(['role_id'], 'Roles'));
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;
/**
* Roles Model
*
* @property \Cake\ORM\Association\BelongsTo $Systems
*/
class RolesTable extends Table
{
/**
* Initialize method
*
* @param array $config The configuration for the Table.
* @return void
*/
public function initialize(array $config)
{
parent::initialize($config);
$this->table('roles');
$this->displayField('name');
$this->primaryKey(['id', 'system_id']);
$this->belongsTo('Systems', [
'foreignKey' => 'system_id',
'joinType' => 'INNER'
]);
}
/**
* Default validation rules.
*
* @param \Cake\Validation\Validator $validator Validator instance.
* @return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator)
{
$validator
->add('id', 'valid', ['rule' => 'numeric'])
->allowEmpty('id', 'create');
$validator
->requirePresence('name', 'create')
->notEmpty('name');
$validator
->add('status', 'valid', ['rule' => 'numeric'])
->requirePresence('status', 'create')
->notEmpty('status');
return $validator;
}
/**
* Returns a rules checker object that will be used for validating
* application integrity.
*
* @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
* @return \Cake\ORM\RulesChecker
*/
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->existsIn(['system_id'], 'Systems'));
return $rules;
}
}
我的src/Model/Table/UsersTable:
<?php
namespace App\Model\Table;
use Cake\ORM\Table;
use Cake\Validation\Validator;
class UsersTable extends Table{
public function validationDefault(Validator $validator){
return $validator
->notEmpty('username', 'O campo nome de usuário é obrigatório')
->notEmpty('password', 'O campo senha é obrigatório')
->notEmpty('role', 'O campo perfil é obrigatório')
->add('role', 'inList', [
'rule' => ['inList', ['admin', 'author']],
'message' => 'Escolha um perfil válido'
]
);
}
}
?>
用户 jose_zap 在 #cakephp @freenode 中回答:
在 RolesUsersTable.php 初始化函数中,我为 $this->belongsTo 调用添加了一个参数,包括 'bindingKey' 和值 'id'。所以这个旧代码:
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
'joinType' => 'INNER'
]);
$this->belongsTo('Roles', [
'foreignKey' => 'role_id',
'joinType' => 'INNER'
]);
变成了这个:
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
'bindingKey' => 'id',
'joinType' => 'INNER'
]);
$this->belongsTo('Roles', [
'foreignKey' => 'role_id',
'bindingKey' => 'id',
'joinType' => 'INNER'
]);