我正在尝试使用laravel编写一个过滤器系统,情况如下:
这是我的$inputs
数组。颜色是复选框,材料是下拉列表:
$inputs = [
'colors' => ['green' => 'green', 'red' => 'red'],
'material' => 'wood',
]
这是我正在查看的表(variants_values
)。这是我存储变体的所有属性组合的地方:
id | product_id | variant_id | property_id | label | value
550 91 213 1 color green
551 91 213 2 material wood
552 91 214 1 color red
552 91 214 2 material plastic
这是我的要求。目标是返回相应的产品,因此我使用whereHas()
方法对我的variants_values
进行子查询:
foreach($inputs as $key => $input) {
$products->whereHas('variants_values', function($query) use($key, $input) {
if(is_array($input)) {
$query->where('label', $key)->whereIn('value', $input);
} elseif(!empty($input)) {
$query->where('label', $key)->where('value', $input);
}
});
}
除了以下一种情况外,此代码效果很好:
green
的颜色和wood
的材料,我希望退回我的产品91
。但是
red
的颜色和wood
的材料,则我不会有任何结果,因为red
的变体是plastic
而非wood
制成的。实际上,产品91
仍会返回,因为实际上,我的代码不会检查它是否与$inputs
相同;
所以我需要在代码中写一些内容:
foreach($inputs as $key => $input) {
$products->whereHas('variants_values', function($query) use($key, $input) {
if(is_array($input)) {
$query->where('label', $key)->whereIn('value', $input);
} elseif(!empty($input)) {
$query->where('label', $key)->where('value', $input);
}
##
$query->where('Verify that the variant ID is the same or something like that');
##
});
}
我知道我离解决方案不远,但实际上我被困在这里。
谢谢您的帮助
答案 0 :(得分:0)
看来这需要更复杂的查询。
将其放入您的Product
模型中:
public function variants() {
return $this->belongsToMany(Variant::class, 'variants_values');
}
将variants_values
关系复制到您的Variant
模型中。
然后尝试:
$products->whereHas('variants', function($query) use($inputs) {
foreach($inputs as $key => $input) {
$query->whereHas('variants_values', function($query) use($key, $input) {
$query->whereColumn('product_id', 'products.id');
if(is_array($input)) {
$query->where('label', $key)->whereIn('value', $input);
} elseif(!empty($input)) {
$query->where('label', $key)->where('value', $input);
}
});
}
});