2012-02-25 40 views
2

我有一個ForumForumTag HABTM關係。我也有一個名爲@tags的變量數組。這個數組包含一些ForumTag的名字。我希望能夠查詢和查找具有數組的所有值的所有論壇。我現在有:查詢Activerecord HABTM關係以包含數組中的所有元素

@forums = Forum.joines(:forum_tags)。凡(:forum_tags => {:名稱=> @tags})包括(:forum_tags)。所有

但是,這將返回數組中具有AT LEAST ONE值的所有論壇。

回答

4

以下將要求論壇擁有@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變量中。

+0

工程就像一個魅力。後續:如果我想要,然後將leftover_tags變量設置爲包含在查詢中的所有剩餘標籤。例如,如果有一個標有['foo','bar','blah']的標籤,標籤數組只有['foo','bar'] ....我想讓leftover_tags爲['' blah'] – Marc 2012-02-26 00:32:12

+0

我已經更新了答案,隨後查詢了剩餘標籤。 – 2012-02-26 15:44:57

相關問題