Laravel 7 雄辩的嵌套条件,用于使用枢轴进行过滤
Posted
技术标签:
【中文标题】Laravel 7 雄辩的嵌套条件,用于使用枢轴进行过滤【英文标题】:Laravel 7 eloquent nested conditions for filtering with pivot 【发布时间】:2021-06-27 18:17:31 【问题描述】:我正在做一个项目,但陷入了困境。假设我有 4 张桌子;供应商、产品、category_products(枢轴)、类别。 假设每个表在下面都有这一列:
供应商 ID 姓名 等等
产品 ID 供应商 ID 姓名 股票 等等
category_products ID product_id 类别ID 时间戳
类别 ID 名字
型号: 供应商
public function products()
return $this->hasMany('App\Models\Sewa\Products', 'vendor_id')->with('product_images');
产品
public function product_category()
return $this->hasOne('App\Models\Sewa\ProductCategories', 'product_id');
产品类别
public function category()
return $this->belongsTo('App\Models\Sewa\Categories', 'category_id');
public function product()
return $this->belongsTo('App\Models\Sewa\Products', 'product_id');
类别
public function product_category()
return $this->hasMany('App\Models\Sewa\ProductCategories', 'category_id');
我试图按类别和价格过滤来自供应商的产品。但是每个产品只有一个类别,但一个类别可以用于许多产品。 我所做的是:
$vendors = Vendors::with('products.product_category.category')->whereHas('products', function($query) use($request)
if($request->category !== 'all')
$query->whereHas('product_category', function($query) use($request)
$query->where('category_id', $request->category);
);
if($request->price === 'low')
$query->whereBetween('price', [0, 10000]);
if($request->price === 'middle')
$query->whereBetween('price', [10000, 250000]);
if($request->price === 'high')
$query->where('price', '>', 250000);
);
我试图让类别 id = 1,但我得到了全部记录。我真的不知道为什么它忽略了 where 子句条件。我在这里做错了什么?
【问题讨论】:
【参考方案1】:文档:https://laravel.com/docs/8.x/eloquent-relationships#constraining-eager-loads
像这样使用你的关系约束:
$vendors = Vendors::with(['products.product_category.category' => function($request)
// your condition
])->whereHas('products', function($query) use($request)
if($request->category !== 'all')
$query->whereHas('product_category', function($query)
use($request)
$query->where('category_id', $request->category);
);
if($request->price === 'low')
$query->whereBetween('price', [0, 10000]);
if($request->price === 'middle')
$query->whereBetween('price', [10000, 250000]);
if($request->price === 'high')
$query->where('price', '>', 250000);
);
【讨论】:
感谢您的快速回复。但是,如果我使用急切加载,with()
之后的whereHas()
是否必要?【参考方案2】:
感谢我的朋友,我得到了答案。所以基本上,它仍然是一个多对多的关系。如果我错了纠正我。我改变了几件事;
型号
产品
public function product_category()
return $this->hasMany('App\Models\Sewa\ProductCategories', 'product_id');
我将hasOne()
更改为hasMany()
,但两者都运行良好。但在这种情况下,我的朋友告诉我使用多对多关系,即使每个产品只有一个类别。
控制器
$vendors = Vendors::with(['products' => function($query) use($request)
if($request->category !== 'all')
$query->whereHas('product_category', function($query) use($request)
$query->where('category_id', $request->category);
);
if($request->price === 'low')
$query->whereBetween('price', [0, 10000]);
if($request->price === 'middle')
$query->whereBetween('price', [10000, 250000]);
if($request->price === 'high')
$query->where('price', '>', 250000);
, 'products.product_category.category']);
这个逻辑解决了我的问题。我没有首先使用whereHas()
,而是使用带有条件的急切加载,就像@Psycho 提到的那样。感谢我的朋友和@Psycho。
注意:如果这段代码看起来“乱七八糟”,请告诉我,这样我和所有阅读本文的人都可以提高成为更好的程序员。
【讨论】:
您本可以接受我的回答,我会根据您当前的解决方案对其进行编辑 我在卡住之前尝试了不同的组合。在您回答之前已找到此解决方案。我通过给你一个赞成票来感谢你的回答。但是您的解决方案不起作用,因为我已经这样做了。以上是关于Laravel 7 雄辩的嵌套条件,用于使用枢轴进行过滤的主要内容,如果未能解决你的问题,请参考以下文章