想象一本书和章节模型。每个章节belongs_to :book
和一本书has_many :chapters
。我们在章节中有范围,例如:very_long
返回超过300页的章节。
很多时候,我们希望获得300页以上任何章节的所有书籍。我们通常实现这一目标的方式如下:
# book.rb
scope :has_very_long_chapter, -> { where(id: Chapter.very_long.select(:book_id) }
但是,正如您可以想象的那样,每当我们想要按章节范围过滤书籍时,代理范围变得非常繁琐。有没有更惯用或更清洁的方法来实现这一目标?
答案 0 :(得分:1)
要获取这些图书,您可以使用ActiveRecord::SpawnMethods#merge
,而不必使用其他版本:
Book.joins(:chapters).merge(Chapter.very_long)
答案 1 :(得分:-1)
我认为您可以做的一件事就是使用joins/merge
class Book < ARBase
scope :with_long_chapters, ->{ joins(:chapter).merge(Chapter.very_long) }
end
class Chapter < ARBase
scope :very_long, -> { logic for querying chapters with over 300 pages }
end
编辑(#2):更可重复使用的范围
class Book < ARBase
scope :by_chapter_page_count, ->(pages){ joins(:chapter).merge(Chapter.by_page_count pages) }
scope :with_climax, -> { joins(:chapter).merge(Chapter.by_category :climax) }
scope :long_with_climax, -> { by_chapter_page_count(400).with_climax }
end
class Chapter < ARBase
scope :by_page_count, ->(pages) { where("pages > ?", pages }
scope :by_category, ->(category) { where category: category }
end
Book.by_chapter_page_count(100)
您可以通过编写示波器的方式获得相当的创意