在Laravel 5中合并“与”和“whereHas”

2022-08-30 16:23:20

我在Laravel 5中使用了Eloquent的这段代码,它运行良好:

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

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

基本上,目标是仅获取具有其筛选提交的用户,其中任何一个都有。但是,在 WhereHas 和具有相同回调函数的方法运行似乎很浪费。有没有办法简化它?

谢谢。


答案 1

就性能而言,您无法在此处真正优化任何内容(除非您要从雄辩的关系移动到连接)。无论是否使用 ,都将运行两个查询。一个用于选择所有用户,另一个用于加载相关模型。添加条件时,将添加一个子查询,但它仍然是两个查询。whereHaswhereHas

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

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();

答案 2

宏观”方式(Laravel 5.4+)

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

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

推荐