在Laravel 5中合并'with'和'whereHas'

Kri*_*rva 16 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();
Run Code Online (Sandbox Code Playgroud)

基本上,目标是只为那些用户提供过滤后的提交,其中包含任何一个.然而,似乎浪费了同时运行whereHas具有相同回调函数的方法.有没有办法简化它?

谢谢.

luk*_*ter 36

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

但是,从语法上来说,您可以通过向模型添加查询范围(或者甚至是基本模型,如果您想更频繁地使用它)来优化这一点:

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

用法:

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


Ija*_*een 5

”方式(Laravel 5.4+

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

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