是否可以檢查has_many中是否存在多個關聯?在這種情況下,我想檢查是否有一本書有三個標籤「a」,「b」和「c」。Rails:檢查has_many中是否存在關聯
(圖書和標籤通過許多關聯到很多。)
if Book.all.tags.find("a", "b", "c").any?
# Yay!
# There is at least one book with all three tags (a, b & c)
end
是否可以檢查has_many中是否存在多個關聯?在這種情況下,我想檢查是否有一本書有三個標籤「a」,「b」和「c」。Rails:檢查has_many中是否存在關聯
(圖書和標籤通過許多關聯到很多。)
if Book.all.tags.find("a", "b", "c").any?
# Yay!
# There is at least one book with all three tags (a, b & c)
end
我用這個查詢結構:
Book
.select('distinct books.*')
.joins(:tags)
.where('tags.slug' => ['a', 'b', 'c'])
.group("pages.id")
.having("count(*) = #{['a', 'b', 'c'].size}")
我認爲這會做的伎倆(適用於has_many
):
Book.includes(:tags).where(tags: { name: ['a', 'b', 'c'] }).any?
其分解:
includes
告訴Rails使用急切加載來加載標籤,而不是一次加載一個標籤。這也會導致它在查詢中注意tags
並生成更智能的查詢。
where
條件非常簡單,並且傳遞數組只是將=
比較轉換爲IN ('a', 'b', 'c')
條件。
Rails是智能的any?
,所以不是加載記錄(它產生一個花哨的查詢,順便說一句)它會生成一個只加載計數。
我從來沒有找到一種優雅的導軌方式來解決這個問題,所以希望別人會有更好的答案。
粗魯的方法是下降到SQL。我正在寫這個內存不足,所以可能有語法問題。
在Book模型中就像這樣。這些表的短名稱不會與父查詢衝突。
def self.with_tag(tag)
where("EXISTS (SELECT 1 from books_tags bt, tags t where bt.tag_id = t.id
and bt.book_id = books.id and t.name = ?)", tag)
end
然後,您可以撥打Book.with_tag('a').with_tag('b').with_tag('c')
或定義其他方法。不確定是否需要範圍變量。
def self.with_all_tags(tags)
scope = self.scoped
tags.each do |t|
scope = scope.with_tag(t)
end
end
非常感謝你。我在這裏找到了一個解決方案:[http://stackoverflow.com/questions/5835696/rails-has-many-through-associations-find-with-and-condition-not-or-conditio][1] [1]:http://stackoverflow.com/questions/5835696/rails-has-many-through-associations-find-with-and-condition-not-or-conditio – Railsana