2017-02-09 10 views
2

ブックとチャプターモデルを想像してみてください。各章belongs_to :bookと、書籍です。例えば、:very_longは300ページ以上の章を返します。belongs_toアソシエーションのRailsスコープ

多くの場合、300ページ以上の章を持つすべての書籍を取得したいと考えています。あなたが想像できるように、しかし

# book.rb 
scope :has_very_long_chapter, -> { where(id: Chapter.very_long.select(:book_id) } 

それがプロキシにスコープ我々は章スコープでブックをフィルタするたびにかなり退屈な取得します。私たちは通常、これを実現する方法はとても似ています。これを達成するための慣用的な方法や清潔な方法はありますか?

答えて

-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 

EDIT(#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) 

をスコープ

+1

これは少し洗練されていますが、子モデルで再利用するたびに新しいスコープを記述する必要はありません。 – jtmarmon

+0

@jtmarmon子モデルで再利用するたびに新しいスコープを書くことによって、何を意味するのかを明確にすることができますか?私はあなたが何を得ているのか分かりません。別のクエリを使用する場合は、新しいスコープを定義する必要があります。 – Sean

+0

@jtmarmon私の答えを少し修正して、範囲をより再利用できるかどうかを見てみましょう。 – Sean

1

これらの書籍を入手するにはActiveRecord::SpawnMethods#mergeを使用し、別のスコープを使用する必要はありません。

Book.joins(:chapters).merge(Chapter.very_long) 
関連する問題