I have three models, Outfit, Product, and a join model OutfitProduct (Outfit has many Products through OutfitProducts).
I would like to find outfits that contain only exact product matches.
So far I have this
def by_exact_products(products)
joins(outfit_products: :product)
.where(outfit_products: { product: products })
.group("outfits.id")
.having('count(outfits.id) = ?', products.size)
end
The above returns any outfit that contains the products I am searching for, even if it is not an exact match. I would like it to return only outfits that are an exact match.
Example: Assume we have the following outfits made up of the following products:
outfit_1.products = [product_1, product_2, product_3, product_4]
outfit_2.products = [product_1, product_2]
outfit_3.products = [product_1, product_2, product_3]
If I passed [product_1, product_2, product_3] to my query, it will return outfit_1 and outfit_3 - I would like it to only return outfit_3 which is an exact match.
UPDATE (More info)
Calling the query with an array of three products produces the following query:
SELECT "outfits".*
FROM "outfits"
INNER JOIN "outfit_products"
ON "outfit_products"."outfit_id" = "outfits"."id"
INNER JOIN "products"
ON "products"."id" = "outfit_products"."product_id"
WHERE "outfit_products"."product_id" IN ( 18337, 6089, 6224 )
GROUP BY outfits.id
HAVING ( Count(outfits.id) = 3 )