Rails,acts_as_taggable_on:如何获取没有标签的所有文章

时间:2011-10-20 17:22:50

标签: ruby-on-rails ruby tags find acts-as-taggable-on

我正在使用acts-as-taggable-on。我有文章模型:

class Article < ActiveRecord::Base
  acts_as_taggable_on :tags
end

我知道如何查找标签为“tag”的所有文章。根据README,解决方案是:Article.tagged_with("tag")

但如何找到没有任何标签的所有文章?

5 个答案:

答案 0 :(得分:6)

使用经典的SQL技巧:左连接然后选择第二个ID为空的行。

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

答案 1 :(得分:3)

根据the source对于act-as-taggable-on,您可以使用: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)

答案 2 :(得分:1)

SQL方式看起来很糟糕,使用map肯定会很慢。

在这里,您可以通过两个查询(第4栏):

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

答案 3 :(得分:0)

您可以使用选择功能。我想SQL解决方案效率更高,但这看起来更好一点:

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

答案 4 :(得分:0)

我相信这是从Rails 5开始可以做的。

Article.left_joins(:taggings).where(taggings: { tag_id: nil })