Cakephp 3-BelongTomany association中的附加ID字段';这张桌子怎么了
我一直在从事一个CakePHP3项目,该项目的某些部分比较复杂,而且该框架的官方文档似乎没有给出我想要的答案。需要做以下几件事: 用户可以属于多个项目。在每个项目中,属于当前项目的每个用户都可以访问应用程序的不同部分,这由一个名为Resources的表处理,该表存储资源ID 简言之,用户A可以访问项目A和项目B中不同数量的资源 我建立了以下关联:Cakephp 3-BelongTomany association中的附加ID字段';这张桌子怎么了,cakephp,orm,cakephp-3.x,Cakephp,Orm,Cakephp 3.x,我一直在从事一个CakePHP3项目,该项目的某些部分比较复杂,而且该框架的官方文档似乎没有给出我想要的答案。需要做以下几件事: 用户可以属于多个项目。在每个项目中,属于当前项目的每个用户都可以访问应用程序的不同部分,这由一个名为Resources的表处理,该表存储资源ID 简言之,用户A可以访问项目A和项目B中不同数量的资源 我建立了以下关联: 通过UsersProjects属于任何项目的用户 用户通过UsersResources拥有任何资源 在users_resources-table I中
$usersTable = TableRegistry::get('Users');
$user = $usersTable->get(129);
$data = [
'resources' => [
[
'id' => 48,
'_joinData' => [
'project_id' => 2
]
]
]
];
$user = $usersTable->patchEntity($user, $data, ['associated' => ['Resources']]);
if ($usersTable->save($user)) {
$this->out('success');
} else {
$this->out('fail');
}
{
"id": 129,
"email": "john.doe@example.com",
"created": null,
"modified": "2016-02-05T20:50:06+0000",
"firstname": "John",
"lastname": "Doe",
"type": 1,
"resources": [
{
"id": 48,
"type": "r",
"_joinData": {
"project_id": 2
}
}
]
}
用户稳定:
$this->belongsToMany('Resources', [
'foreignKey' => 'user_id',
'targetForeignKey' => 'resource_id',
'joinTable' => 'users_resources',
'through' => 'UsersResources'
]);
资源稳定:
$this->belongsToMany('Users', [
'foreignKey' => 'resource_id',
'targetForeignKey' => 'user_id',
'joinTable' => 'users_resources',
'through' => 'UsersResources'
]);
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
'joinType' => 'INNER'
]);
$this->belongsTo('Resources', [
'foreignKey' => 'resource_id',
'joinType' => 'INNER'
]);
$this->belongsTo('Projects', [
'foreignKey' => 'project_id',
'joinType' => 'INNER'
]);
UsersResourcesTable:
$this->belongsToMany('Users', [
'foreignKey' => 'resource_id',
'targetForeignKey' => 'user_id',
'joinTable' => 'users_resources',
'through' => 'UsersResources'
]);
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
'joinType' => 'INNER'
]);
$this->belongsTo('Resources', [
'foreignKey' => 'resource_id',
'joinType' => 'INNER'
]);
$this->belongsTo('Projects', [
'foreignKey' => 'project_id',
'joinType' => 'INNER'
]);
UsersResourcesTable类中还实现了一个buildRules函数,用于帮助实现数据完整性:
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->existsIn(['user_id'], 'Users'));
$rules->add($rules->existsIn(['resource_id'], 'Resources'));
$rules->add($rules->existsIn(['project_id'], 'Projects'));
$rules->add($rules->isUnique(['user_id', 'resource_id', 'project_id']));
return $rules;
}
数据按如下方式保存:
$usersTable = TableRegistry::get('Users');
$user = $usersTable->get(129);
$data = [
'resources' => [
[
'id' => 48,
'_joinData' => [
'project_id' => 2
]
]
]
];
$user = $usersTable->patchEntity($user, $data, ['associated' => ['Resources']]);
if ($usersTable->save($user)) {
$this->out('success');
} else {
$this->out('fail');
}
{
"id": 129,
"email": "john.doe@example.com",
"created": null,
"modified": "2016-02-05T20:50:06+0000",
"firstname": "John",
"lastname": "Doe",
"type": 1,
"resources": [
{
"id": 48,
"type": "r",
"_joinData": {
"project_id": 2
}
}
]
}
修补实体后的实体数据:
$usersTable = TableRegistry::get('Users');
$user = $usersTable->get(129);
$data = [
'resources' => [
[
'id' => 48,
'_joinData' => [
'project_id' => 2
]
]
]
];
$user = $usersTable->patchEntity($user, $data, ['associated' => ['Resources']]);
if ($usersTable->save($user)) {
$this->out('success');
} else {
$this->out('fail');
}
{
"id": 129,
"email": "john.doe@example.com",
"created": null,
"modified": "2016-02-05T20:50:06+0000",
"firstname": "John",
"lastname": "Doe",
"type": 1,
"resources": [
{
"id": 48,
"type": "r",
"_joinData": {
"project_id": 2
}
}
]
}
当使用项目id 2保存数据时,保存将按预期进行。当我保存相同的数据但将项目id更改为1(用户id和资源id将保持不变)时,将从表中删除项目id为2的前一行。期望的行为显然是旧记录将保留在表中。不过我注意到,在UsersTable的资源关联定义中添加一个值为“append”的saveStrategy选项将使保存正确进行(不会删除具有project_id 2的行)。但是,当我尝试在使用append策略时保存现有记录时,保存将失败(保存结果为false)
因此,如果使用替换策略,先前的数据将被删除,如果使用追加策略,现有行的更新将导致cake透视图中的错误。我认为这个错误是在规则检查期间由于唯一的规则而抛出的
我认为替换策略是可行的,但似乎忽略了project_id-field值,这会导致在使用不同的project_id添加新行时删除以前的数据(具有相同的用户_id和资源_id)
所以我的问题是:
是否可以将第三个id字段添加到BelongToMany association的槽表中,这样额外的字段也会被视为id字段,以便框架知道何时更新或向联接表插入记录
这个想法是表中的所有三个字段都是唯一的。现在,框架似乎丢弃了额外的字段,因此插入和更新无法按预期工作。或者数据库结构中是否存在需要修复的设计缺陷
我更愿意坚持CakePHP约定,但这种情况似乎很难解决。感谢您的指导 “放弃”和“不起作用”到底是什么意思?您的实际关联配置是什么样子的?您如何保存数据?数据是什么样子的?你明白了吗?我用你要求的信息编辑了这个问题,希望它能帮助你弄清楚到底发生了什么