在我的Yii2应用程序中,我拥有模型User
,Group
和Role
,它们具有以下关系:用户是组的成员,并且在这些组中具有角色,和/或在全局中角色。
我使用一个联接表User_Role
和列UserId
,RoleId
和GroupId
来存储模型之间链接上的信息。如果GroupId
为NULL
,则角色为全局角色,否则包含用户在其中具有该角色的组的ID。
据我了解,Yii2的BaseActiveRecord::link/unlink
机制并不是要(取消)链接两个以上的模型。链接可以正常进行,因为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
方法。但是,也许有更聪明的多模型链接方式将不需要定制查询。有什么建议吗?
谢谢。