如何根据Laravel中关系的条件获取列表

时间:2014-06-04 12:01:06

标签: php laravel laravel-4

我有一个用户角色实体,具有多对多关系。在我的角色表中,我有一个名为visible的列,它存储一个布尔值。如果用户有一个不可见的角色(至少有一个),我想将他从结果集中排除。

我可以在我的查询中获取相关角色并只是迭代它们并找出那种方式,但我真正想要做的只是让我的查询只返回具有所有可见角色的用户而不是过滤之后查询。

类似的东西:

public function scopeVisible($query)
{
  $query->whereHas('roles', function($q){
    // and here i want to find that thing out
  })     
}

2 个答案:

答案 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();