Tech Racho エンジニアの「?」を「!」に。
  • 開発

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

概要

原著者の許諾を得て翻訳・公開いたします。

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_emailemailがblankの場合にnilを返していることです。

ではどちらにすればよいか

チームの好みに合わせて決めればよいでしょう。その代わり、一度決めたらアプリ全体でその書き方を統一します。

関連記事

Railsのdefault_scopeは使うな、絶対(翻訳)

肥大化したActiveRecordモデルをリファクタリングする7つの方法(翻訳)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。