Laravel 7 eloquent 使用数据透视过滤的嵌套条件
Laravel 7 eloquent nested conditions for filtering with pivot
我正在做一个项目,遇到了一个问题。假设我有 4 table;供应商、产品、category_products(枢轴)、类别。
假设每个 table 下面都有此列:
供应商
ID
姓名
等等
产品
ID
vendor_id
姓名
股票
等等
category_products
ID
product_id
category_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 子句条件。我这里做错了什么?
文档: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);
}
});
感谢我的朋友,我得到了答案。所以基本上,它仍然是一个多对多的关系。如果我错了纠正我。我改变了几件事;
型号
产品
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。
注意:如果此代码看起来 'messy' 请告诉我,这样我和阅读此代码的每个人都可以改进成为更好的程序员。
我正在做一个项目,遇到了一个问题。假设我有 4 table;供应商、产品、category_products(枢轴)、类别。 假设每个 table 下面都有此列:
供应商 ID 姓名 等等
产品 ID vendor_id 姓名 股票 等等
category_products ID product_id category_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 子句条件。我这里做错了什么?
文档: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);
}
});
感谢我的朋友,我得到了答案。所以基本上,它仍然是一个多对多的关系。如果我错了纠正我。我改变了几件事;
型号
产品
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。
注意:如果此代码看起来 'messy' 请告诉我,这样我和阅读此代码的每个人都可以改进成为更好的程序员。