【问题标题】:Eloquent way of filtering on foreign key外键过滤的雄辩方式
【发布时间】:2020-08-11 02:19:06
【问题描述】:

我有一个 Product 模型,它有很多 SalePrices(随着时间的推移而变化),存储在两个通过外键和雄辩关系链接的数据库表中:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{

  public function sale_prices()
  {
      return $this->hasMany('App\SalePrices');
  }
}

我要做的是根据传入的 Http 请求查询过滤产品,因此我在控制器中获得产品列表:

$products = Product::whereIn('type', $request->types)->where('active', 1);

然后,我检查最低价格或最高价格,并尝试进行相应的过滤:

if ($request->has('min_price')) {
    $products->sale_prices()->where('price', '>=', $request->min_price);
}

if ($request->has('max_price')) {
    $products->sale_prices()->where('price', '<=', $request->max_price);
}

 $products = $products->get();

这不起作用,并给我这个错误:

Call to undefined method Illuminate\Database\Eloquent\Builder::sale_prices()

我知道 $products 变量现在是项目的集合,但我不确定如何在这些项目上应用我的过滤器。我可以遍历它们,但我将如何应用我正在寻找的 where 子句?

【问题讨论】:

    标签: php laravel eloquent


    【解决方案1】:

    尝试在产品中传递get方法。

    $products = Product::whereIn('type', $request->types)->where('active', 1)->get();    
    

    【讨论】:

      【解决方案2】:

      sale_prices()是Model对象的一个​​方法,Eloquent builder不能调用它。

      使用whereHas检查哪个产品与min_price或max_price有关系。

      $products = Product::whereIn('type', $request->types)->where('active', 1);
      
      if ($request->has('min_price')) {
          $products->whereHas('sale_prices', function($query) use ($min_price) {
              $query->where('price', '>=', $min_price);
          });
      }
      
      if ($request->has('max_price')) {
          $products->whereHas('sale_prices', function($query) use ($max_price) {
              $query->where('price', '<=', $max_price);
          });
      }
      $products->whereIn('type', $request->types)->where('active', 1)->get();
      
      

      【讨论】:

      • 在最终调用中添加“whereIn”是否重要,或者我可以只添加“$products = $products->get();”吗?
      • @CornelVerster 不客气。如果在get之后加上whereIn,就是使用集合方法whereIn,如果在get()之前加上whereIn,就是使用eloquent-builder whereIn方法,是diff,虽然结果是一样的,我仍然建议在get() 之前使用whereIn,因为它会在数据库中执行,最后从数据库中得到较小的结果。不需要在服务器中过滤结果。
      • @CornelVerster 和$products = $products-&gt;whereIn('type', $request-&gt;types)-&gt;where('active', 1)-&gt;get() 您可以将结果设置为 $products。
      猜你喜欢
      • 2017-04-18
      • 2020-08-20
      • 1970-01-01
      • 2021-10-02
      • 1970-01-01
      • 2013-06-19
      • 2017-08-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多