Rails, acts_as_taggable_on: как получить все статьи без тегов - PullRequest
1 голос
/ 20 октября 2011

Я использую Act-as-Taggable-On .У меня есть статья Article:

class Article < ActiveRecord::Base
  acts_as_taggable_on :tags
end

Я знаю, как найти все статьи с тегом «tag».Согласно README решение: Article.tagged_with("tag").

Но как найти все статьи без тегов?

Ответы [ 5 ]

6 голосов
/ 24 октября 2011

Используйте классический трюк SQL: левое соединение, затем выберите строки, где второй идентификатор равен нулю.

Article.
  joins(%Q{LEFT JOIN taggings ON taggings.taggable_id=articles.id AND taggings.taggable_type='Article'}).
  where('taggings.id IS NULL')
3 голосов
/ 24 октября 2011

Согласно источнику для действия-как-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)
1 голос
/ 27 мая 2014

SQL выглядит хакерски, и использование карты наверняка будет медленным.

Здесь вы можете обойтись двумя запросами (rails 4):

ids = Taggings.where(taggable_type: "Article").collect(&:taggable_id).uniq
Article.where.not(id: ids)
0 голосов
/ 23 апреля 2019

Я считаю, что это то, что вы можете сделать с рельсами 5.

Article.left_joins(:taggings).where(taggings: { tag_id: nil })
0 голосов
/ 04 апреля 2012

Вы можете просто использовать функцию выбора. Я думаю, что SQL-решение намного эффективнее, но выглядит немного лучше:

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