我正在为产品设置过滤功能。我有2个模型:Product
和Attribute
(BelongsToMany关系)
属性表:
id name
-------------
1 RAM
2 HDD
产品表:
id name
-----------------
1 Product 1
2 Product 2
3 Product 3
4 Product 4
数据透视表如下:
id attribute_id product_id value
----------------------------------------------------
1 1 (RAM) 1 8GB
2 2 (HDD) 1 256GB
3 1 (RAM) 2 8GB
4 2 (HDD) 2 256GB
5 1 (RAM) 3 4GB
6 2 (HDD) 4 512GB
过滤产品时,用户选择RAM => [4GB, 8GB]
和HDD => 256GB
。
我想获得具有RAM - 4GB
OR RAM - 8GB
AND HDD - 256GB
的产品。这表示产品具有RAM - 4GB, HDD - 256GB
AND RAM - 8GB, HDD - 256GB
属性,将满足过滤条件。与上面的数据库相比,我将获得ID为1和2的产品(产品3具有RAM 4GB
但没有HDD 256
,因此不算在内)。
这是我的代码,但无法正常运行。
$products = Product::whereHas('attributes', function ($query) {
$query->whereIn('attribute_id', [1, 2]);
$query->whereIn('value', ['4GB', '8GB', '256GB']);
})->get();
或
$products = Product::whereHas('attributes', function ($query) {
$query->where(function ($query) {
$query->where('attribute_id', 1)
->whereIn('value', ['4GB', '8GB']);
})->orWhere(function ($query) {
$query->where('attribute_id', 2)
->whereIn('value', ['256GB']);
});
})->get();
答案 0 :(得分:0)
尝试以下方法:
$products = Product::whereHas('attributes', function ($query) {
$query
->whereIn('attribute_id', [1, 2])
->whereIn('value', ['4GB', '8GB', '256GB']);
})->get();
您必须将那些whereIn()
链接起来。
在method signature中,您可以注意到第三个可选的$boolean
参数:
whereIn(string $column, mixed $values, string $boolean = 'and', bool $not = false)
更新:raw SQL。在您的情况下,我宁愿使用原始的Eloquent查询。