【问题标题】:Merge 'with' and 'whereHas' in Laravel 5在 Laravel 5 中合并 'with' 和 'whereHas'
【发布时间】:2015-06-17 23:20:56
【问题描述】:

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

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

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

基本上,目标是只获取那些提交过滤后的提交的用户,其中任何一个都有。 但是,使用相同的回调函数同时运行 whereHaswith 方法似乎很浪费。有没有办法简化它?

谢谢。

【问题讨论】:

  • 不,没有其他方法(使用雄辩的关系查询 ofc)。为什么会浪费?
  • 好吧,因为我们要过滤两次提交的条件;我只是希望有一种解决方案可以使它成为一个查询而不是更多,但是@lukasgeiter 说得很清楚。
  • 为什么这个答案票数太少?

标签: php laravel eloquent laravel-5


【解决方案1】:

就性能而言,您在这里无法真正优化任何东西(除非您要从 eloquent 关系转移到连接)。不管有没有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();

【讨论】:

  • 我有这个问题两天了,现在它就像一个魅力。
  • 你拯救了我的一天谢谢
  • 为了便于阅读,我可能也将其重命名为 withHas
  • 我将它添加到一个特征中,我可以轻松地在我想要的所有模型中使用它。非常推荐!
【解决方案2】:

我想使用静态函数扩展来自@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();

【讨论】:

  • 但在这种情况下,您不能将其与其他查询混合使用。这应该是您必须从模型中静态调用的第一个函数,但情况并非总是如此。
【解决方案3】:

ma​​croable”方式(Laravel 5.4+

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

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

【讨论】:

  • 在 Laravel 5.8 中我必须这样做: \Illuminate\Database\Eloquent\Builder::macro('withAndWhereHas', function($relation, $constraint){ return $this->whereHas($relation , $constraint)->with([$relation => $constraint]); });
猜你喜欢
  • 2016-04-15
  • 1970-01-01
  • 2018-10-26
  • 2019-06-09
  • 1970-01-01
  • 1970-01-01
  • 2019-07-08
  • 1970-01-01
  • 2019-01-22
相关资源
最近更新 更多