以下將要求論壇擁有@tags
陣列中的所有論壇標籤。我假設forum
將不會有多次相同的forum_tag
。
@forums = Forum.joins(:forum_tags).where(:forum_tags => {:name => @tags}).group("forums.id").having(['COUNT(*) = ?', @tags.length]).includes(:forum_tags).all
這將產生一個SQL查詢類似如下:
@tags = ['foo', 'bar']
SELECT forums.id, forum_tags.id FROM forums
LEFT OUTER JOIN forum_tags_forums on forum_tags_forums.forum_id = forums.id
LEFT OUTER JOIN forum_tags ON forum_tags.id = forum_tags_forums.forum_tag_id
WHERE forum_tags.name IN ('foo', 'bar')
GROUP BY forums.id
HAVING COUNT(*) = 2;
這將集團所有的連接表中的行通過匹配給定的標記,論壇。如果COUNT
函數的值爲您要查找的標籤總數(並且沒有重複的對),則論壇必須包含所有標籤。
爲了得到剩餘的標籤(問題在評論中問):
forum_tags = ForumTag.where(:name => @tags)
@forums_with_leftovers = Forum.select("forums.*, GROUP_CONCAT(forum_tags.name) AS leftover_tags").joins(:forum_tags).where(['forums.id IN (?) AND NOT forum_tags.id IN (?)', @forums, forum_tags]).group("forums.id").all
每個Forum
對象@forums_with_leftovers
將有一個包含逗號分隔的每個論壇對象標籤列表中的附加屬性leftover_tags
不是在原始@tags
變量中。
工程就像一個魅力。後續:如果我想要,然後將leftover_tags變量設置爲包含在查詢中的所有剩餘標籤。例如,如果有一個標有['foo','bar','blah']的標籤,標籤數組只有['foo','bar'] ....我想讓leftover_tags爲['' blah'] – Marc 2012-02-26 00:32:12
我已經更新了答案,隨後查詢了剩餘標籤。 – 2012-02-26 15:44:57