Rails tips: モデルのクエリをカプセル化する2つの方法(翻訳)

概要 原著者の許諾を得て翻訳・公開いたします。 英語記事: Encapsulating queries in a Rails model – Ruby on Rails / ActiveRecord 原文公開日: 2018/01/01 著者: Paweł Dąbrowski Rails: モデルのクエリをカプセル化する2つの方法(翻訳) 要点: サービスやコントローラなどのクラスからデータベースクエリのロジックを分離することは間違いなく優れた方法です。ロジックをモデルに置く場合、次の2とおりの方法が使えます。 1. クラスメソッド化する def self.recent order(created_at: :desc) end 2. ActiveRecordのスコープAPIを使う scope :recent, -> { order(created_at: :desc) } どちらにすればよいか ActiveRecordのスコープはどっちみちクラスメソッドに変換されるので、どちらを選ぶかは見た目の問題に過ぎません。ただし、 スコープはいついかなるときでもチェイン可能である点がポイントです。 次のように、スコープの定義内に条件を含めた場合でもチェインできます。 scope :by_email, -> |email| { where(email: email) if email.present? } クラスメソッドで同じことをした場合、メソッドをチェインできないことがあります。 def self.by_email(email) where(email: email) if email.present? end チェインできない理由は、self.by_emailのemailがblankの場合にnilを返していることです。 ではどちらにすればよいか チームの好みに合わせて決めればよいでしょう。その代わり、一度決めたらアプリ全体でその書き方を統一します。 関連記事 Railsのdefault_scopeは使うな、絶対(翻訳) 肥大化したActiveRecordモデルをリファクタリングする7つの方法(翻訳)