scopeの使い方をレシピアプリを例に解説、設定していきます。
scopeとは
そもそもscopeとは何なのか? Railsガイドでは以下のように説明されています。
スコープを設定することで、関連オブジェクトやモデルへのメソッド呼び出しとして参照される、よく使用されるクエリを指定することができます。スコープでは、where、joins、includesなど、これまでに登場したすべてのメソッドを使用できます。どのスコープメソッドも、常にActiveRecord::Relationオブジェクトを返します。このオブジェクトに対して、別のスコープを含む他のメソッド呼び出しを行なうこともできます。
単純なスコープを設定するには、クラスの内部でscopeメソッドを使用し、スコープが呼び出されたときに実行して欲しいクエリをそこで渡します。
出典:Railsガイド
むむ、なんか難しそう...
と思われる方も多いかもしれませんが簡潔にまとめるとscopeとはwhere、order、limitなどの複数のクエリをまとめたメソッドになります。
文章だけでは難しく感じると思うので実際にコードを見ていきましょう。
scopeの使い方の例
例えば以下のようにしてレシピ情報を取得するとします。
class RecipesController < ApplicationController
...
def index
@recipes = Recipe.order(created_at: :desc).limit(10)
end
...
end
上記のコードのorder(created_at: :desc).limit(10)
の部分をrecentと命名しモデルにまとめていきます。
class Recipe < ApplicationRecord
...
scope :recent, -> {order(created_at: :desc).limit(10}
...
end
上記で定義したscopeを使用します。
class RecipesController < ApplicationController
...
def index
@recipes = Recipe.recent
end
...
end
以上が使い方の例になります。
scopeのメリット
scopeを使うことによって以下のようなメリットがあります。
・ コードが簡潔になる
・ 修正する場合修正箇所が少なくなる
・ 自分で命名できるので直感的に扱いやすくなる
先ほどの例で説明すると以下のコードは同じ意味になりますが、scopeを使用した方がより簡潔になります。
class RecipesController < ApplicationController
...
def index
#scopeを定義しなかった場合
@recipes = Recipe.order(created_at: :desc).limit(10)
#scopeを定義した場合
@recipes = Recipe.recent
end
...
end
scopeの設定方法
scopeがどんなものか理解できてきたと思うので、設定の仕方について説明していきます。
基本的な設定方法
class モデル名 < ApplicationRecord
scope :スコープ名, -> { 条件式 }
end
第一引数にシンボルを使ってスコープ名設定し、第二引数は-> { 条件式 }とします。
先ほどの例でいうと条件式はorder(created_at: :desc).limit(10)
になります。
引数を使う場合
->のあとに引数を定義すると引数を渡すことができます。
class モデル名 < ApplicationRecord
scope :スコープ名, -> (引数) { 条件式 }
end
先ほどの例で説明するとlimitで取得したい数を引数にします。
class Recipe < ApplicationRecord
...
scope :recent, -> (count) {order(created_at: :desc).limit(count)}
...
end
class RecipesController < ApplicationController
...
def index
@recipes = Recipe.recent(10)
end
...
end