Я хочу создать две "виртуальные" связи между двумя таблицами.
У меня есть таблица 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'
]);
}
}