Dans notre base de données, nous avons trois tables : offres, sports, et la table de jointure deals_sports. Nous souhaitons récupérer les offres qui incluent un ensemble de sports donné, avec l'exigence que tous les sports spécifiés doivent être présents, mais des sports supplémentaires peuvent également être inclus.
Par exemple, en considérant les offres suivantes :
Si nous recherchons des offres contenant « Bodyboard » et « Surf », nous nous attendons à recevoir à la fois « Moyen » et « Tous », mais pas « Léger ». Cependant, notre requête actuelle :
Offer.joins(:sports) .where(sports: { name: ["Bodyboarding", "Surfing"] }) .group("sports.name") .having("COUNT(distinct sports.name) = 2")
Et l'équivalent SQL :
SELECT "offers".* FROM "offers" INNER JOIN "offers_sports" ON "offers_sports"."offer_id" = "offers"."id" INNER JOIN "sports" ON "sports"."id" = "offers_sports"."sport_id" WHERE "sports"."name" IN ('Bodyboarding', 'Surfing') GROUP BY sports.name HAVING COUNT(distinct sports.name) = 2;
Ne renvoie aucun résultat.
Pour rectifier cela, nous modifions notre requête pour regrouper par l'identifiant de l'offre au lieu du nom du sport :
SELECT o.* FROM sports s JOIN offers_sports os ON os.sport_id = s.id JOIN offers o ON os.offer_id = o.id WHERE s.name IN ('Bodyboarding', 'Surfing') GROUP BY o.id -- !! HAVING count(*) = 2;
ou dans ActiveRecord :
class Offer < ActiveRecord::Base has_and_belongs_to_many :sports def self.includes_sports(*sport_names) joins(:sports) .where(sports: { name: sport_names }) .group('offers.id') .having("count(*) = ?", sport_names.size) end end
Cette modification garantit que nous regroupons de manière appropriée les résultats et appliquons les critères de filtrage nécessaires pour récupérer les offres souhaitées qui incluent les sports spécifiés.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!