2009-09-12 7 views
1

J'ai un modèle de livre et un modèle de balise et un modèle de jointure. Le modèle de livre a de nombreuses balises dans le modèle de jointure. Comment trouver des livres qui ont à la fois l'étiquette «A» ET l'étiquette «B»?Une à plusieurs requête avec jointures

Cela fonctionne pour Just A:

Book.all(:joins => 'tags', :conditions => {'tags.name' => 'A'}) 

Cela fonctionne pour A ou B (ou semble):

Book.all(:joins => 'tags', :conditions => {'tags.name' => ['A','B']}) 

Mais je voudrais trouver tous les livres avec A et B .

+0

Pouvez-vous inclure le livre, le tag et votre modèle Join pour plus de clarté? – Yaraher

Répondre

0

Voici une approche: trouver tous les livres et se débarrasser des livres qui n'ont pas étiquette A et B

Book.all - Book.all(:joins=>'tags', :conditions=>[tags.name <> 'A' and tags.name <> 'B'] 
+0

Les résultats de l'exécution de la requête ci-dessus suggèrent qu'un OR est exécuté. Les résultats contiennent des livres qui ont l'une ou l'autre étiquette, alors qu'ils ne doivent inclure que des livres avec les deux étiquettes. – LDK

0

Cela devrait le faire:

Book.all(:joins => 'tags', :conditions => "tags.name = 'A' and tags.name = 'B'") 
+0

Cela évaluera à zéro et en fait quand je l'exécute, il retourne un tableau vide. – LDK

0

La seule façon que je peux penser à faire est d'utiliser plusieurs jointures sur la table de jointure, une pour chaque étiquette que vous voulez et ensemble. Cela ne fonctionne pas très bien, mais ça marche bien pour deux. La requête que vous voulez, en supposant que votre joindre modèle est appelé marquages ​​avec une book_id clé étrangère:

SELECT DISTINCT books.* FROM books 
    INNER JOIN taggings t1 ON t1.book_id = book.id 
    INNER JOIN taggings t2 ON t2.book_id = book.id 
WHERE t1.id = (SELECT id FROM tags WHERE name = 'A') 
    AND t2.id = (SELECT id FROM tags WHERE name = 'B') 

Vous pouvez essayer d'utiliser cela avec la méthode find, bonne chance :) Probablement plus facile à utiliser juste find_by_sql, comme ceci:

Book.find_by_sql(["SELECT DISTINCT books.* FROM books 
     INNER JOIN taggings t1 ON t1.book_id = book.id 
     INNER JOIN taggings t2 ON t2.book_id = book.id 
    WHERE t1.id = (SELECT id FROM tags WHERE name = ?) 
     AND t2.id = (SELECT id FROM tags WHERE name = ?)", 'A', 'B') 

Cela suppose que tags.name est unique.

+0

Intéressant, malheureusement j'ai beaucoup plus que deux tags, donc cette approche n'est pas si propre. – LDK

Questions connexes