查询Laravel查询范围内的相关模型

Rus*_*ack 11 laravel eloquent laravel-4

我有一个查询范围方法,用于过滤模型作者在Foo模型上的结果.复杂的是作者没有直接关系.

Foo属于Bar and Bar属于User.如果Foo属于User,我可以这样做:

public function scopeAuthorOnly($query, User $user)
{
    return $query->whereuser_id($user->id);
}
Run Code Online (Sandbox Code Playgroud)

这显然不起作用,因为Foo模型没有user_id列,而是有一个bar_id列.但是,我不确定如何以过滤user_id的方式构建查询.

有什么指针吗?

Ard*_*rda 17

您可以whereHas()在范围中使用查询关系.

假设您users()在此模型中具有关系函数.那就是这样的:

public function scopeAuthorOnly($query, User $user)
{
    return $query->whereHas('users', function($q) use($user){
        $q->where('id', $user->id);
    });
}
Run Code Online (Sandbox Code Playgroud)

更新:你也可以嵌套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);
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

更多信息:这里


cas*_*red 8

您也可以使用关系执行此操作(无需借助手动连接):

public function scopeAuthorOnly($query, User $user)
{
    $query->whereHas(array('Bar' => function($query) use($user){
                $query->where('user_id', '=', $user->id);
            }));
}
Run Code Online (Sandbox Code Playgroud)

编辑:现在使用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);
            });
}
Run Code Online (Sandbox Code Playgroud)


Rus*_*ack 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;
}
Run Code Online (Sandbox Code Playgroud)

  • 这比whereHas更好,因为它使用表索引并且工作效率更高,但是不要忘记添加 - > select("users.*")否则laravel可以给你"id"或来自错误表的任何其他字段,并且没有错误将被抛出. (2认同)