0

我在使用表配置的两个表之间有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();

当我通过向其中添加用户来添加或编辑组时,$datainbeforeMarshal()

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'

}

所以看起来 Marshaller 正在从组中删除第二个“重复”用户,即使_joinData是不同的。默认saveStrategy值为replace,但手动将其更改为append也不会添加第二个关联。

如何_joinData使用相同的连接表将相同的用户添加到不同的组中。

4

1 回答 1

2

marshaller 使用主键来标识记录,现有实体的集合将只保存一个用户实体实例,因此即使 marshaller 将添加不同的连接数据集,它也会将其设置在同一个实体上。 . 长话短说,编组器(还)没有能力做你想做的事。如果还没有问题,你可能想在 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;
});
于 2019-05-15T21:03:34.970 回答