Rails在belongs_to关联上的范围

时间:2017-02-09 22:53:08

标签: ruby-on-rails ruby activerecord

想象一本书和章节模型。每个章节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) }

但是,正如您可以想象的那样,每当我们想要按章节范围过滤书籍时,代理范围变得非常繁琐。有没有更惯用或更清洁的方法来实现这一目标?

2 个答案:

答案 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)

您可以通过编写示波器的方式获得相当的创意