php - Laravel Eloquent - 过滤关系
问题描述
我的 Laravel 项目中有两个主要模型。ProductMaster 是主要产品数据所在的位置,而 Product 是保存每个产品的变化和每个客户的价格的模型。我不允许更改此模型,以防您想知道。
我的问题是如何进行雄辩的查询以获取 ProductMaster 数据,其中包含由客户端(以及其他参数)过滤的产品。我试过 whereHas 但它没有用。
这是我的模型:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ProductMaster extends Model
{
protected $table = 'product_masters';
protected $primaryKey = 'id';
protected $fillable = ['code','title'];
public function products(){
return $this->hasMany(Product::class,'master_id');
}
}
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Models\ProductMaster;
class Product extends Model
{
protected $table = 'products';
protected $primaryKey = 'id';
protected $fillable = ['sku', 'stock', 'brand', 'size', 'priceList', 'master_id', 'client'];
public function productMaster(){
return $this->belongsTo(ProductMaster::class,'master_id');
}
}
这是我试图做的查询:
//QUERY WITH FILTERS
$products = ProductMaster::whereHas('products', function($query)
use($filterBrand, $filterCats, $filterSizes, $clientCode)
{
$query->where('client', $clientCode);
$query->whereIn('brand', $filterBrand);
$query->whereIn('size', $filterSizes);
})
->where('title', 'LIKE', '%' . $request->find . '%')
->orderby($order[0], $order[1])
->paginate(6)
->withQueryString();
这个查询有效,但我没有得到我所需要的。这给了我所有具有具有该参数的产品的 ProductMaster,但是在集合 $products 中,它放置了具有该 master_id 的所有产品,而不仅仅是具有该参数的产品。
这是sql:
select * from `product_masters` where exists (select * from `products` where `product_masters`.`id` = `products`.`master_id` and `client` = ? and `products`.`brand` in (?) and `category` in (?) and `client` = ?) and `title` LIKE ? order by `title` asc
这是一些示例数据:SQL Fiddle
任何人都可以帮助我吗?谢谢。
解决方案
如果您想过滤产品以预先加载,并且还过滤以仅加载拥有这些产品的产品主机,您的查询应该是这样的:
$products = ProductMaster::
with([
'products' =>
fn($query) => $query
->where('client', $clientCode)
->whereIn('brand', $filterBrand)
->whereIn('size', $filterSizes)
])
->whereHas('products',
fn($query) => $query
->where('client', $clientCode)
->whereIn('brand', $filterBrand)
->whereIn('size', $filterSizes)
)
->where('title', 'LIKE', '%' . $request->find . '%')
->orderby($order[0], $order[1])
->paginate(6)
->withQueryString();
您甚至可以将 with 和 whereHas 函数上的查询传递给控制器内部的私有函数,以保持克隆更干净。
推荐阅读
- networking - 如何在 Google Kubernetes Engine 中设置特定节点的外部 IP?
- php - 在 WooCommerce 中出现错误时强制重定向到购物车
- python - Python如何使用列表名称作为数据框中的列名
- java - 我如何在另一个类中实现一个类的方法
- python - 无法使用请求从脚本标签中抓取不同专辑的链接?
- c# - 如何修复 Xamarin 'System.ArgumentNullException: '值不能为空。参数名称:地址'异常
- php - Laravel 多重归属和关系 - Eloquent
- r - 如何在 R ggplot 中设置用于不同组的形状?
- python - 移动时图像旋转
- android - 我需要从 onTouchEvent 中删除 TAP_TIMEOUT 延迟