简体   繁体   中英

Stuck with laravel query

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:

  • If I check green color and wood material, I want that my product 91 is returned, which is the case.

BUT

  • If I check 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM