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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18521178/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 02:36:57  来源:igfitidea点击:

Querying a related model within a Laravel query scope

laravellaravel-4eloquent

提问by Russ Back

I have a query scope method that filters results on a Foo model by the author of the model. The complication is that the author is not directly related.

我有一个查询范围方法,可以过滤模型作者对 Foo 模型的结果。复杂的是作者没有直接关系。

Foo belongs to Bar and Bar belongs to User. If Foo belonged to User, I could just do this:

Foo 属于 Bar,Bar 属于 User。如果 Foo 属于用户,我可以这样做:

public function scopeAuthorOnly($query, User $user)
{
    return $query->whereuser_id($user->id);
}

This obviously won't work as the Foo model has no user_id column and instead has a bar_id column. However I'm not sure how I can build the query in a way that would filter the user_id.

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

Any pointers?

任何指针?

采纳答案by Russ Back

Found a solution:

找到了解决办法:

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;
}

回答by Arda

You can use whereHas()in scopes to query relationships.

您可以whereHas()在范围内使用来查询关系。

Let's assume you have a users()relation function in this model. Then it'd be something like this:

假设您users()在此模型中有一个关系函数。然后它会是这样的:

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

Update:You can also nest whereHasstatements: If the current Foohas a relation named bar, and barhas a relation called users, it'd be like this:

更新:您还可以嵌套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);
        });
    });
}

More info: here

更多信息:这里

回答by casafred

You can also do this using relations (without resorting to manual joins):

您也可以使用关系来做到这一点(无需借助手动连接):

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

Edit: now using whereHasinstead of with(Laravel >= 4.1 only). Thanks for the correction Arda.

编辑:现在使用whereHas而不是with(仅限 Laravel >= 4.1)。感谢阿尔达的更正。

Edit: in 4.2 the syntax of whereHas has changed, so that the relationship name is parameter 1 and the closure is parameter 2 (rather than being passed in as an array):

编辑:在 4.2 中 whereHas 的语法已更改,因此关系名称为参数 1,闭包为参数 2(而不是作为数组传入):

public function scopeAuthorOnly($query, User $user)
{
    $query->whereHas('Bar', function($query) use($user){
                $query->where('user_id', '=', $user->id);
            });
}