🔍

Rails Model スコープとクラスメソッドの違い

2024/10/22に公開

スコープとクラスメソッドの役割

モデルのクエリに名前をつけて簡潔に定義できる機能。
再利用性と可読性を高める。

相違点

スコープ

  • 結果がnilの場合に、必ず ActiveRecord::Relation を返却する。
  • 他のスコープやクエリメソッドとチェーンが可能。
    • クラスメソッドでもメソッドチェーンを使用できるが、返り値がnilの可能性があるため、エラーとなる場合がある。

クラスメソッド

  • 戻り値を自由に設定できる
  • 複雑なロジックの実装により向いている
    • 動的な条件分岐など複雑なロジックを実装する場合は、スコープによるチェーンよりも可読性が高い
  • 引数のデフォルト値を設定できる

引数について

以前のRailsガイドでは、

スコープで引数を使用するのであれば、クラスメソッドとして定義する方が推奨されます。

と引数を使う場合はクラスメソッドの使用を推奨されていた。
しかし、v6以降はその記述が削除されているため、引数を使う場合でもスコープを使用して問題はない。

5.2: https://railsguides.jp/v5.2/active_record_querying.html
7.2: https://railsguides.jp/v7.2/active_record_querying.html

使い分け

  • 簡単なクエリをカプセル化したい時はスコープを使用する
  • チェーンを用いる前提であればスコープを使用する
  • 条件がマッチしない場合に、nilを返却したい場合はクラスメソッドを使用する
  • 引数を用いてより複雑なロジックを実装したい場合はクラスメソッドを使用する

その上で、スコープのチェーンをモデル内でクラスメソッドにまとめると、さらに簡潔な記述が可能。
https://techracho.bpsinc.jp/hachi8833/2023_02_14/53537

参考

https://gihyo.jp/book/2020/978-4-297-11462-6
https://railsguides.jp/active_record_querying.html#スコープ
https://qiita.com/SoarTec-lab/items/6e5f7781edf8d3fe4889
https://techracho.bpsinc.jp/hachi8833/2023_02_14/53537
https://techracho.bpsinc.jp/hachi8833/2018_01_16/51052

Discussion