I'm trying to write a filter system using laravel, here is the situation:
Here is my $inputs
array. Colors are checkboxes, and material is a dropdown :
$inputs = [
'colors' => ['green' => 'green', 'red' => 'red'],
'material' => 'wood',
]
Here is the table ( variants_values
) I'm looking at. This is where I stock all combination of properties for my variants :
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
Here is my request. The goal is to return corresponding products, so I use a whereHas()
method to make a subquery over my 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);
}
});
}
This code works quite well except one situation:
green
color and wood
material, I want that my product 91
is returned, which is the case. BUT
red
color and wood
material, I want no results because the red
variant is made of plastic
, not wood
. Actually, the product 91
is still returned because actually, my code don't check if it's the same variant that correspond to the $inputs
;
So I need something in my code that would say :
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');
##
});
}
I know I'm not far from the solution but I'm stuck here actually.
Thank you for your help
It looks like this requires a more complex query.
Put this in your Product
model:
public function variants() {
return $this->belongsToMany(Variant::class, 'variants_values');
}
Copy the variants_values
relationship to your Variant
model.
Then try this:
$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);
}
});
}
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.