我有一个用户和角色实体,具有多对多关系。在我的角色表中,我有一个名为visible
的列,它存储一个布尔值。如果用户有一个不可见的角色(至少有一个),我想将他从结果集中排除。
我可以在我的查询中获取相关角色并只是迭代它们并找出那种方式,但我真正想要做的只是让我的查询只返回具有所有可见角色的用户而不是过滤之后查询。
类似的东西:
public function scopeVisible($query)
{
$query->whereHas('roles', function($q){
// and here i want to find that thing out
})
}
答案 0 :(得分:2)
让我们首先确定我们正在使用的表格
user
id - integer
name - string
role
id - integer
visible - bool in the form of SMALLINT 0 or 1
user_role
user_id - integer
role_id - integer
我们首先在普通的旧SQL中解决它。像这样:
SELECT * FROM user
INNER JOIN user_role ON user_role.user_id = user.id
INNER JOIN role ON role.id = user_role.role_id
GROUP BY user.id
HAVING COUNT(user_role.user_id) = SUM(role.visible);
这里的关键是HAVING
声明。我们会计算用户拥有的角色数量,然后对可见列进行总结。如果所有角色都可见,那么用户与角色的关系数量将等于可见角色的数量。
现在把它转换成Laravel说话。为此,我们必须使用Laravel的查询构建器。
$visibleUsers = DB::table('user')
->join('user_role', 'user_role.user_id', '=', 'user.id')
->join('role', 'role.id', '=', 'user_role.role_id')
->groupBy('user.id')
->havingRaw('COUNT(`user_role`.`user_id`) = SUM(`role`.`visible`)')
->get();
答案 1 :(得分:0)
我不熟悉whereHas但我会尝试这样的事情
public function scopeVisible($query)
{
return $query->whereHas('roles', function($q) {
$q->where('visible', '=', true);
});
}
然后使用它:$usersVisible = User::visible()->get();