несколько принадлежащих друг другу ассоциаций между двумя таблицами - PullRequest
0 голосов
/ 20 мая 2019

Я хочу создать две "виртуальные" связи между двумя таблицами.

У меня есть таблица Users и таблица Groups, и я хочу связать пользователя с группой как «писатель», «редактор» или оба.

У меня есть следующие таблицы:

  • users: id | username
  • groups: id | name
  • groups_writers: id | user_id | group_id
  • editors_groups: id | user_id | group_id

Я не уверен, как создать несколько ассоциаций между двумя таблицами.Это попытка создать отношения.

class UsersTable extends Table
{
    public function initialize(array $config)
    {
        $this->belongsToMany('EditorGroups', [
            'joinTable' => 'editors_groups'
        ])
            ->setClassName('Groups')
            ->setForeignKey('user_id')
            ->setTargetForeignKey('group_id');

        $this->belongsToMany('WriterGroups', [
            'joinTable' => 'groups_writers'
        ])
            ->setClassName('Groups')
            ->setForeignKey('user_id')
            ->setTargetForeignKey('group_id');
    }
}

class GroupsTable extends Table
{
    public function initialize(array $config)
    {
        $this->belongsToMany('Editors', [
            'joinTable' => 'editors_groups'
        ])
            ->setClassName('Users')
            ->setForeignKey('group_id')
            ->setTargetForeignKey('user_id');

        $this->belongsToMany('Writers', [
            'joinTable' => 'groups_writers'
        ])
            ->setClassName('Users')
            ->setForeignKey('group_id')
            ->setTargetForeignKey('user_id');
    }
}

Но это не сохраняет информацию об ассоциации.

$group = $this->Groups->newEntity();
$data = [
    'name' => 'test group',
    'editors' => [
        '_ids' => [
            (int) 0 => '1'
        ]
    ],
    'writers' => [
        '_ids' => [
            (int) 0 => '2'
        ]
    ]
];
$group = $this->Groups->patchEntity($group, $data, [
    'associated' => ['Editors', 'Writers']
]);
$this->Groups->save($group);

patchEntity s в

object(App\Model\Entity\Group) {

    'name' => 'test group',
    '[new]' => true,
    '[accessible]' => [
        'name' => true,
        'editors_groups' => true,
        'groups_writers' => true
    ],
    '[dirty]' => [
        'name' => true
    ],
    '[original]' => [],
    '[virtual]' => [],
    '[hasErrors]' => false,
    '[errors]' => [],
    '[invalid]' => [],
    '[repository]' => 'Groups'

}

, вероятно, потому что patchEntity не знаетсопоставьте первичный ключ editors и writers со строками в users.

После добавления строки в таблицу соединения вручную, например,

INSERT INTO `editors_groups` (`id`, `user_id`, `group_id`) VALUES ('1', '1', '1');

, переходя к /users/edit/1 или /groups/view/1 показывает правильные ассоциации.


edit

Ассоциация работает после добавления обязательных доступных полей.

class User extends Entity
{
    protected $_accessible = [
        'username' => true,
        'editor_groups' => true,
        'writer_groups' => true
    ];
}

class Group extends Entity
{
    protected $_accessible = [
        'name' => true,
        'editors' => true,
        'writers' => true
    ];
}

Чтобы использовать through, я добавилследующее:

class UsersTable extends Table
{
    public function initialize(array $config)
    {
        $this->belongsToMany('EditorGroups')
            ->setClassName('Groups')
            ->setForeignKey('user_id')
            ->setTargetForeignKey('group_id')
            ->setThrough('EditorsEditorGroups');

        $this->belongsToMany('WriterGroups')
            ->setClassName('Groups')
            ->setForeignKey('user_id')
            ->setTargetForeignKey('group_id')
            ->setThrough('WritersWriterGroups');
    }
}

class GroupsTable extends Table
{
    public function initialize(array $config)
    {
        $this->belongsToMany('Editors')
            ->setClassName('Users')
            ->setForeignKey('group_id')
            ->setTargetForeignKey('user_id')
            ->setThrough('EditorsEditorGroups');

        $this->belongsToMany('Writers')
            ->setClassName('Users')
            ->setForeignKey('group_id')
            ->setTargetForeignKey('user_id')
            ->setThrough('WritersWriterGroups');
    }
}

class EditorsEditorGroupsTable extends Table
{
    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->setTable('editors_groups');
        $this->setDisplayField('id');
        $this->setPrimaryKey('id');

        $this->belongsTo('Editors', [
            'foreignKey' => 'user_id',
            'className' => 'Users'
        ]);
        $this->belongsTo('EditorGroups', [
            'foreignKey' => 'group_id',
            'className' => 'Groups'
        ]);
    }
}
...