我有一个查询范围方法,可以过滤模型作者在Foo模型上的结果。复杂的是作者没有直接关系。
Foo属于Bar and Bar属于User。如果Foo属于User,我可以这样做:
public function scopeAuthorOnly($query, User $user)
{
return $query->whereuser_id($user->id);
}
这显然不起作用,因为Foo模型没有user_id列,而是有一个bar_id列。但是,我不确定如何以过滤user_id的方式构建查询。
任何指针?
答案 0 :(得分:16)
您可以在范围中使用whereHas()
来查询关系。
假设您在此模型中具有users()
关系函数。那就是这样的事情:
public function scopeAuthorOnly($query, User $user)
{
return $query->whereHas('users', function($q) use($user){
$q->where('id', $user->id);
});
}
更新:您还可以嵌套whereHas
语句:如果当前Foo
具有名为bar
的关系,并且bar
有关系叫users
,它就像这样:
public function scopeAuthorOnly($query, User $user)
{
return $query->whereHas('bar', function($q) use($user){
return $q->whereHas('users', function($q2) use($user){
$q2->where('id', $user->id);
});
});
}
更多信息:here
答案 1 :(得分:8)
您也可以使用关系(不使用手动连接)来执行此操作:
public function scopeAuthorOnly($query, User $user)
{
$query->whereHas(array('Bar' => function($query) use($user){
$query->where('user_id', '=', $user->id);
}));
}
修改:现在使用whereHas
代替with
(仅限Laravel> = 4.1)。感谢Arda的修正。
编辑:在4.2中whereHas的语法已经改变,因此关系名称是参数1,闭包是参数2(而不是作为数组传入):
public function scopeAuthorOnly($query, User $user)
{
$query->whereHas('Bar', function($query) use($user){
$query->where('user_id', '=', $user->id);
});
}
答案 2 :(得分:5)
找到解决方案:
public function scopeAuthorOnly($query, User $user)
{
$query
->join('bars', 'foos.bar_id', '=', 'bars.id')
->join('users', 'bars.user_id', '=', 'users.id')
->where('users.id', '=', $user->id);
return $query;
}