Laravel Eloquent query model which has exactly a number of association in a n-to-m relationship

Viewed 243

I have a project where I have the following Models :

  • Products
  • FeatureTypes
  • Features
  • Variants

And the tables and relationships are the following :

Database Schema Diagram

I have a request where I want to retrieve the Variants from a Product with some specific Features. A Variant can have 1 or many Features but I want to have all Variants if I give one Feature, and have a more specific search on the Variants if I gave more Features, until I have only one Variant which can have only one set of specific Feature.

Here's the code I have for now :

$variants =  $product
->variants()
->whereHas('features', function($query) {
    $query->whereIn('id', json_decode(request('features')));
})
->with('features', 'features.featureType')
->get();  

The request('features') contains a stringified array with ids of Features.

I used Eloquent's whereIn method thinking that it would give me only the variants that have exactly all the Features given in the request.

But while checking the documentation again, I see that it will return any Variants that has at least one Feature given in the request which is not what I need here.

How can I make that Eloquent's query to return me only the Variants that are associated with all the Features given by the request ?

Thanks in advance for you help ! ;)

1 Answers

whereHas() accepts a fourth argument with the number of rows:

$variants = $product
    ->variants()
    ->whereHas('features', function($query) use ($features) {
        $query->whereIn('id', $features);
    }, '=', count($features))
    ->with('features', 'features.featureType')
    ->get();
Related