Как правильно (tm) найти записи без тегов?
Я пытался использовать Entry.tagged_with(nil)
, но он просто возвращает пустой хэш.
Мне это нужно, чтобы я мог перечислить записи, которые мне еще нужно пометить.
Спасибо.
Как правильно (tm) найти записи без тегов?
Я пытался использовать Entry.tagged_with(nil)
, но он просто возвращает пустой хэш.
Мне это нужно, чтобы я мог перечислить записи, которые мне еще нужно пометить.
Спасибо.
Не зная внутренностей действий-как-тегов, я не могу придумать изящного способа, который не включал бы циклические запросы или необработанный SQL. Это читабельно:
need_to_tag = []
Entry.all.each do |e|
need_to_tag << e if e.tag_list.blank?
end
Затем need_to_tag содержит все записи без тегов.
Следующее, кажется, работает для меня:
Entry.includes("taggings").where("taggings.id is null")
Это также должно поддерживать цепочку. Например, должно работать следующее:
Entry.includes("taggings").where("taggings.id is null").where(foo: "bar")
Вот мое решение, чтобы найти фотографии с тегами и без тегов.
scope :with_taggings, where('id in (select taggable_id from taggings where taggable_type = ’Photo‘ and context = ’bibs‘)')
scope :without_taggings, where('id not in (select taggable_id from taggings where taggable_type = ’Photo‘ and context = ’bibs‘)')
Но это работает для модели Photo, но не может быть связано с другими областями.
Я понимаю, что это старо, но сегодня я столкнулся с подобной потребностью. Я просто сделал это с помощью простой области с несколькими запросами:
scope :untagged, lambda {
# first build a scope for the records of this type that *are* tagged
tagged_scope = Tagging.where(:taggable_type => base_class.to_s)
# only fetching the taggable ids
tagged_scope = tagged_scope.select('DISTINCT taggable_id')
# and use it to retrieve the set of ids you *don't* want
tagged_ids = connection.select_values(tagged_scope.to_sql)
# then query for the rest of the records, excluding what you've found
where arel_table[:id].not_in(tagged_ids)
}
Это может быть неэффективно для огромных наборов данных, но подходит для моих целей.