В моем приложении Yii2 у меня есть модели User
, Group
и Role
со следующими отношениями: пользователи являются членами групп и имеют роли в этой группе и / или глобальные роли.
Я использую одну таблицу соединения, User_Role
со столбцами UserId
, RoleId
и GroupId
для хранения информации о связях между моделью.Если GroupId
равно NULL
, роль является глобальной, в противном случае она содержит идентификатор группы, в которой пользователь имеет эту роль.
Насколько я понимаю, механизм BaseActiveRecord::link/unlink
в Yii2 на самом деле не предназначен (не) связывать более двух моделей.Связывание работает нормально, потому что BaseActiveRecord::link
принимает необязательный параметр extraColumns
, в котором я могу передать ['GroupId'=> ... ]
.Однако в BaseActiveRecord::unlink
такого параметра нет, поэтому я вынужден прибегнуть к обходному пути:
// class User
// ...
/**
* Internal. Populated temporarily during relational queries.
* @var int|null
*/
public $groupId = null;
/**
* @return ActiveQuery
*/
public function getUserRoles()
{
$link = ['UserId' => 'id'];
if( $this->groupId) $link['GroupId'] = "groupId";
return $this->hasMany(User_Role::class, $link );
}
/**
* Returns the roles of the user, depending on the groupId property.
* @return ActiveQuery
*/
public function getRoles()
{
return $this
->hasMany( Role::class, ['id' => 'RoleId'] )
->via('userRoles', function(ActiveQuery $query){
return $query->andWhere(['GroupId' => $this->groupId]);
});
}
И установить свойство groupId
перед отменой соединения или выполнением других видов запросов.
Конечно, я мог бы выполнить связывание части "вручную" и не полагаться на метод unlink
.Но, возможно, существуют более разумные способы многомодельных связей, которые не требуют специальных запросов.Есть предложения?
Спасибо.