Laravel 中多层深度关系的查询生成器过滤器

Query Builder filter for multi level deep relationship in Laravel

我选择了一些地块,每个地块都属于通过房屋类型的 hasManyThrough 关系开发的地块。我想在他们的概述页面上通过开发来过滤这些。 Plots 有一个 housetype_id 列,housetypes 有一个 development_id 列。

public function plots()
  {
    return $this->hasManyThrough(Plot::class, Housetype::class);
  }

当我使用我的过滤器时,returns 开发 ID 号为 $development,然后我需要它来仅显示与该开发相关的地块。

我研究过使用 whereHas 或 Join 方法,但无法解决这个问题。当前过滤范围如下。谢谢

public function scopeFilterDevelopment($query)
    {
      $development = request()->input('filter_development');

      if ($development == "") {
        return;
      }

      if(!empty($development)){
        $query->where('development_id', $development);
      }
    }

如果我没看错的话,您希望在其他模型上断言一个条件,HasMany 将在查询完成后将所有对象加载到相关模型。 Eloquent 然后将相关的模型对象绑定到每个对象。

试试从 Laravel 改成 joins。我觉得这正是您想要的:https://laravel.com/docs/5.8/queries#joins

我会使用 whereHas 来过滤关系:

YourModel::whereHas('plots', function($query) {
    $query->filterDevelopment();
})->get();

我还会将查询范围编辑为不依赖请求全局函数,而是将开发值作为参数传递。

你已经做了一个离开的工作然后使用时,你不必使用

if(!empty($development)){
    $query->where('development_id', $development);
  } 

这个不用了,可以用

->when($development=="" ? false : true, function($query) use ($development){
return $query->where('development_id', $development);
})

这是一个完整的例子

$queryBuilder =  DB::table('facturas')->
leftJoin('clientes','clientes.id','=','facturas.clientes_id')->
select('facturas.estados_id as estado','facturas.numero as 
numero',DB::raw('concat(clientes.nombre," ",clientes.apellido) as cliente'))->
when($estados===null ? false: true,function($query) use ($estados){
    return $query->whereIn('facturas.estados_id', $estados);
                        })

whereHas 终于解决了这个问题! (工作中的另一位开发人员带我完成了这个)

关系 -

public function housetype()
    {
      return $this->belongsTo(Housetype::class);
    }

函数 -

public function scopeFilterDevelopment($query)
    {
      if (request()->input('filter_development') == "") {
        return;
      }else{
        $query->whereHas('housetype', function($housetype){
          $housetype->where('development_id', request()->input('filter_development'));
        });
      }
    }

然后 returns 其房屋类型与请求中的 filter_development 匹配 development_id 的任何地块。

感谢大家的意见