一尘不染

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

php

我在Laravel 5中使用Eloquent编写了此代码,该代码运行良好:

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

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

基本上,目标是仅让那些过滤了提交内容的用户拥有其中的任何一个。但是,似乎浪费了在 whereHas带有
相同回调函数的方法上运行的时间。有没有一种方法可以简化它?

谢谢。


阅读 596

收藏
2020-05-29

共1个答案

一尘不染

在性能方面,您实际上无法在此进行任何优化(除非您要从雄辩的关系转向联接)。有或没有whereHas,将运行两个查询。一个选择所有用户,另一个选择加载相关模型。当您添加whereHas条件时,将添加一个子查询,但是仍然是两个查询。

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

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();
2020-05-29