我在两个表之间有一个belongsToMany
关系,该关系是使用through
表进行配置的。
class UsersTable extends Table
{
public function initialize(array $config)
{
$this->belongsToMany('Groups', [
'through' => 'GroupsUsers',
]);
}
}
class GroupsTable extends Table
{
public function initialize(array $config)
{
$this->belongsToMany('Users', [
'through' => 'GroupsUsers',
]);
}
}
class GroupsUsersTable extends Table
{
public function initialize(array $config)
{
$this->belongsTo('Groups');
$this->belongsTo('Users');
}
}
我可以在用户和组之间建立关联,但是我不能弄清楚如何在同一用户和组之间建立多个关联,但是使用不同的_joinData
。
这是建立联接表的方式:
$table = $this->table('groups_users');
$table->addColumn('user_id', 'integer');
$table->addColumn('group_id', 'integer');
$table->addColumn('role', 'string');
$table->create();
当我通过向其添加用户来添加或编辑组时,$data
中的beforeMarshal()
是
object(ArrayObject) {
name => 'test group'
users => [
(int) 0 => [
'id' => (int) 1,
'_joinData' => [
'role' => 'writer'
]
],
(int) 1 => [
'id' => (int) 1,
'_joinData' => [
'role' => 'editor'
]
]
]
}
使用
修补控制器中的实体后$entity = $this->Groups->patchEntity(
$entity,
$data,
['associated' => ['Users._joinData']]
);
我在$entity
中得到以下beforeSave()
object(App\Model\Entity\Group) {
'id' => (int) 1,
'name' => 'test group',
'users' => [
(int) 0 => object(App\Model\Entity\User) {
'id' => (int) 1,
'username' => 'testuser',
'_joinData' => object(Cake\ORM\Entity) {
'role' => 'writer',
'[new]' => true,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'role' => true
],
'[original]' => [],
'[virtual]' => [],
'[hasErrors]' => false,
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'GroupsUsers'
},
'[new]' => false,
'[accessible]' => [
'username' => true,
'groups' => true,
'_joinData' => true
],
'[dirty]' => [
'_joinData' => true
],
'[original]' => [
'_joinData' => [
'role' => 'writer'
]
],
'[hasErrors]' => false,
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Users'
}
],
'[new]' => false,
'[accessible]' => [
'name' => true,
'users' => true
],
'[dirty]' => [
'users' => true,
'modified' => true
],
'[original]' => [
'modified' => object(Cake\I18n\FrozenTime) {
'time' => '2019-05-15T14:41:49+00:00',
'timezone' => 'UTC',
'fixedNowTime' => false
}
],
'[hasErrors]' => false,
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Groups'
}
因此,即使_joinData
不同,看起来Marshaller也正在从组中删除第二个“重复”用户。默认的saveStrategy
是replace
,但是手动将其更改为append
也不会添加第二个关联。
如何使用相同的联接表将同一用户添加到具有不同_joinData
的同一组中。
答案 0 :(得分:1)
封送处理程序使用主键标识记录,然后现有实体的集合将仅保存一个用户实体实例,因此,即使封送处理程序将添加不同的联接数据集,也会将其设置在一个相同的对象上实体...长话短说,编组员还没有能力做您想做的事情。如果还没有over at GitHub,则可能要打开一个问题。
现在,您必须单独保存记录,例如这样(未经测试,但您知道了):
$group = $this->Groups->patchEntity($entity, $data, [
'fieldList' => ['name']
]);
$users = [];
foreach ($data['users'] as $userData) {
$user = $this->Groups->Users->newEntity();
$users[] = $this->Groups->Users->patchEntity($user, $userData);
}
$result = $this->Groups->getConnection()->transactional(function () use ($group, $users) {
if (!$this->Groups->save($group, ['atomic' => false])) {
return false;
}
if (!$this->Groups->Users->link($group, $users, ['atomic' => false])) {
return false;
}
return true;
});