今日の目標
RailsにおけるモデルのScope機能を学ぶ
ファットコントローラにならないようにモデルの定義を考える
モデルのscope機能とは?
モデルのスコープ機能(scope)とは、モデル側であらかじめ特定の条件式に対して名前をつけて定義し、その名前でメソッドの様に条件式を呼び出すことが出来る仕組みのこと。
基本構文
class モデル名 < ApplicationRecord
scope :スコープの名前, -> { 条件式 }
end
例えば 下記のようなインスタンス変数があったとします。
def index
@ladies = Product.where(category_id: "1")
@men = Product.where(category_id: "2")
@home_appliances = Product.where(category_id: "8")
@hobbies = Product.where(category_id: "6")
end
ここの部分をモデルで以下のように定義してあげると
scope :category, ->(category_id) {where(category_id: category_id)
コントローラでの記述を直感的にすることが出来ます
@ladies = Product.category(1)
@men = Product.category(2)
@home_appliances = Product.category(8)
@hobbies = Product.category(6)
なぜ?scope処理を使うのか
条件の追加が簡単にできる
.order(created_at: "DESC")
の条件を加えたい場合 scopeメソッドを使わない場合
def index
@ladies = Product.where(category_id: "1").order(created_at: "DESC")
@men = Product.where(category_id: "2").order(created_at: "DESC")
@home_appliances = Product.where(category_id: "8").order(created_at: "DESC")
@hobbies = Product.where(category_id: "6").order(created_at: "DESC")
end
このように繰り返しの処理を連続して書かなくてはいけません。これはDRYの法則(Don't Repeat Yourself)に反します。
また、常日頃から簡潔なコードを書くことを心がけていないと追加機能を実装する機会が限られてしまいます。
scopeメソッドでは .order(created_at: "DESC")
の一文を書き加えるだけで済みます。
scope :category, ->(category_id) {where(category_id: category_id).order(created_at: "DESC")}
さらに .limit(10) を加えたい場合
def index
@ladies = Product.where(category_id: "1").order(created_at: "DESC").limit(10)
@men = Product.where(category_id: "2").order(created_at: "DESC").limit(10)
@home_appliances = Product.where(category_id: "8").order(created_at: "DESC").limit(10)
@hobbies = Product.where(category_id: "6").order(created_at: "DESC").limit(10)
end
どんどん記述が長くなってしまいます。
scopeメソッドを使うと
モデルの記述に条件を加えるだけ
scope :category, ->(category_id) {where(category_id: category_id).order(created_at: "DESC").limit(10)}
モデルに記載してあげることで コントローラの肥大を防ぐことができます。
def index
@ladies = Product.category(1)
@men = Product.category(2)
@home_appliances = Product.category(8)
@hobbies = Product.category(6)
end
まとめ
条件式に名前を付けられるので、直感的なコードになる
修正箇所を限定することが出来る
コードが短くなる
コードの記述を整理することで様々な機能の追加が実現出来る時もあると思います。
fat-controllerにならないようにモデルで上手く定義しましょう!
参考資料