LoginSignup
2
2

More than 3 years have passed since last update.

【超かんたん】Railsのscopeってなんぞや?

Last updated at Posted at 2021-03-22

scopeの使い方をレシピアプリを例に解説、設定していきます。

scopeとは

そもそもscopeとは何なのか? Railsガイドでは以下のように説明されています。

スコープを設定することで、関連オブジェクトやモデルへのメソッド呼び出しとして参照される、よく使用されるクエリを指定することができます。スコープでは、where、joins、includesなど、これまでに登場したすべてのメソッドを使用できます。どのスコープメソッドも、常にActiveRecord::Relationオブジェクトを返します。このオブジェクトに対して、別のスコープを含む他のメソッド呼び出しを行なうこともできます。
単純なスコープを設定するには、クラスの内部でscopeメソッドを使用し、スコープが呼び出されたときに実行して欲しいクエリをそこで渡します。
出典:Railsガイド

むむ、なんか難しそう...
と思われる方も多いかもしれませんが簡潔にまとめるとscopeとはwhere、order、limitなどの複数のクエリをまとめたメソッドになります。

文章だけでは難しく感じると思うので実際にコードを見ていきましょう。

scopeの使い方の例

例えば以下のようにしてレシピ情報を取得するとします。

app/controllers/recipes_controller.rb
class RecipesController < ApplicationController
...
  def index
    @recipes = Recipe.order(created_at: :desc).limit(10)
  end
...
end

上記のコードのorder(created_at: :desc).limit(10)の部分をrecentと命名しモデルにまとめていきます。

app/controllers/recipes_controller.rb
class Recipe < ApplicationRecord
...
  scope :recent, -> {order(created_at: :desc).limit(10}
...
end

上記で定義したscopeを使用します。

app/controllers/recipes_controller.rb
class RecipesController < ApplicationController
...
  def index
    @recipes = Recipe.recent
  end
...
end

以上が使い方の例になります。

scopeのメリット

scopeを使うことによって以下のようなメリットがあります。
・ コードが簡潔になる
・ 修正する場合修正箇所が少なくなる
・ 自分で命名できるので直感的に扱いやすくなる

先ほどの例で説明すると以下のコードは同じ意味になりますが、scopeを使用した方がより簡潔になります。

app/controllers/recipes_controller.rb
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で取得したい数を引数にします。

app/controllers/recipes_controller.rb
class Recipe < ApplicationRecord
...
  scope :recent, -> (count) {order(created_at: :desc).limit(count)}
...
end
app/controllers/recipes_controller.rb
class RecipesController < ApplicationController
...
  def index
    @recipes = Recipe.recent(10)
  end
...
end
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2