Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

thorlucas's avatar

Help me build this query

Hi! Sorry for the boring question, but I'm having trouble building this query in Eloquent.

I have a product with several skus. Each sku has many attributes.

Each attribute has a type which could be something like "size" or "color", and a value, which would be something like "M", or "black".

Each product has an arbitrary number of attributes, which I've made selectable in a form.

Now, I have a list of each attribute and its value.

[
    'size' => 'M',
    'color' => 'black',
]

Great. Now I have to fetch the SKU(s) which correspond to these particular attributes.

For example, this works when I have just ONE attribute.

$product->skus->whereHas('attributes', function($query) {
    return $query->where(['type' => 'size', 'value' => 'M']);
})->get();

But how do I build a query that returns only the skus that have attributes which match ALL of the qualifications?

Edit: And remember, these attributes are arbitrary in number. I can't hardcode it; I just have to pass the array of type-value pairs.

Edit: I figured out how to do this manually – but again it doesn't allow for the arbitrary number of attributes. Plus, it's clunky. Something like this:

$product->skus->whereHas('attributes', function($query) {
    return $query->where(['type' => 'size', 'value' => 'M']);
})->whereHas('attributes', function($query) {
    return $query->where(['type' => 'color', 'value' => 'white']);
})->get();
0 likes
1 reply
hpiaia's avatar

You can do it the same way but with a loop:

$filters = [
    ['type' => 'size', 'value' => 'M'],
    ['type' => 'color', 'value' => 'white']
];

$products = $product->skus;

foreach($filters as $filter) {
    $products = $products->whereHas('attributes', function($query) use ($filter) {
        return $query->where($filter);
    });
}

$products = $products->get();

something like that, sorry if the syntax is wrong i wrote that here in the browser

Please or to participate in this conversation.