2011-10-20 147 views

回答

6

使用經典的SQL技巧:left join,然後選擇第二個ID爲空的行。

Article. 
    joins(%Q{LEFT JOIN taggings ON taggings.taggable_id=articles.id AND taggings.taggable_type='Article'}). 
    where('taggings.id IS NULL') 
+0

恕我直言,這種感覺哈克,而不是像鐵軌.. – daniel

+0

@daniel,有沒有好的導軌的工作方式與複雜的連接。除此之外,請參閱http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html –

+0

是的,我同意'Article.tagged_with(Tag.all.map (&:to_s),:exclude => true)'是更多的Rails方式。 但我使用的Rails 2.3,並希望使用它像一個named_scope所以這是唯一的方法... – petRUShka

3

根據the source的行爲-AS-加標籤上,你可以使用:exclude選項:

## 
# Return a scope of objects that are tagged with the specified tags. 
# 
# @param tags The tags that we want to query for 
# @param [Hash] options A hash of options to alter you query: 
#      * <tt>:exclude</tt> - if set to true, return objects that are *NOT* tagged with the specified tags 
#      * <tt>:any</tt> - if set to true, return objects that are tagged with *ANY* of the specified tags 
#      * <tt>:match_all</tt> - if set to true, return objects that are *ONLY* tagged with the specified tags 
#      * <tt>:owned_by</tt> - return objects that are *ONLY* owned by the owner 

所以在您的實例,只是做:

Article.tagged_with("tag", :exclude => true) 

編輯:剛纔意識到你問的文章沒有任何標籤,在這種情況下,你需要提供清單所有標籤的方法:

Article.tagged_with(Tag.all.map(&:to_s), :exclude => true) 
0

您可以使用select函數。我猜的SQL解決方案是更有效的,但這個看起來有點更漂亮:

Artical.all.select{|a| a.tags.count == 0 } 
1

的SQL的方式看起來hackie,並使用地圖將是肯定慢。

在這裏,您可以用兩個查詢(軌道4)獲得通過:

ids = Taggings.where(taggable_type: "Article").collect(&:taggable_id).uniq 
Article.where.not(id: ids) 
相關問題