Yii2 ActiveRecord связать / отменить связь с более чем одной моделью - PullRequest
0 голосов
/ 02 октября 2018

В моем приложении 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.Но, возможно, существуют более разумные способы многомодельных связей, которые не требуют специальных запросов.Есть предложения?

Спасибо.

...