合并'与'和' whereHas'在Laravel 5

时间:2015-04-12 16:48:58

标签: php laravel eloquent laravel-5

我在Laravel 5中有这个代码,使用Eloquent,它运行得很好:

$filterTask = function($query) use ($id) {
    $query->where('taskid', $id);
};

User::whereHas('submissions', $filterTask)->with(['submissions' => $filterTask])->get();

基本上,我们的目标是只为那些拥有过滤提交的用户提供服务。 但是,使用相同的回调函数运行 whereHas with 方法似乎浪费了。有没有办法简化它?

感谢。

3 个答案:

答案 0 :(得分:32)

在性能方面,你可以在这里真正优化任何东西(除非你要从雄辩的关系转变为联接)。无论有没有whereHas,都会运行两个查询。一个选择所有用户另一个加载相关模型。当您添加whereHas条件时,会添加子查询,但它仍然是两个查询。

但是,从语法上来说,你可以通过向模型添加query scope来优化这一点(如果你想更频繁地使用它,甚至可以添加基础模型):

public function scopeWithAndWhereHas($query, $relation, $constraint){
    return $query->whereHas($relation, $constraint)
                 ->with([$relation => $constraint]);
}

用法:

User::withAndWhereHas('submissions', function($query) use ($id){
    $query->where('taskid', $id);
})->get();

答案 1 :(得分:1)

可宏”方式( Laravel 5.4 +

将其添加到服务提供商的boot()方法中。

\Illuminate\Database\Eloquent\Builder\Eloquent::macro('withAndWhereHas', function($relation, $constraint){
    return $this->whereHas($relation, $constraint)->with([$relation => $constraint]);
});

答案 2 :(得分:0)

我想使用静态函数扩展@lukasgeiter的答案。

public static function withAndWhereHas($relation, $constraint){
    return (new static)->whereHas($relation, $constraint)
        ->with([$relation => $constraint]);
}

用法相同

User::withAndWhereHas('submissions', function($query) use ($id){
    $query->where('taskid', $id);
})->get();