1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Rails モデルのscope処理でコードを見やすくしよう

Last updated at Posted at 2020-03-09

今日の目標 

RailsにおけるモデルのScope機能を学ぶ
ファットコントローラにならないようにモデルの定義を考える

モデルのscope機能とは?

モデルのスコープ機能(scope)とは、モデル側であらかじめ特定の条件式に対して名前をつけて定義し、その名前でメソッドの様に条件式を呼び出すことが出来る仕組みのこと。

基本構文

class モデル名 < ApplicationRecord
  scope :スコープの名前, -> { 条件式 }
end

例えば 下記のようなインスタンス変数があったとします。

controller
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

ここの部分をモデルで以下のように定義してあげると

model
scope :category, ->(category_id) {where(category_id: category_id)

コントローラでの記述を直感的にすることが出来ます

controller
 @ladies = Product.category(1) 
 @men = Product.category(2) 
 @home_appliances = Product.category(8) 
 @hobbies = Product.category(6) 

なぜ?scope処理を使うのか

条件の追加が簡単にできる

.order(created_at: "DESC")の条件を加えたい場合 scopeメソッドを使わない場合

controller
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")の一文を書き加えるだけで済みます。

model
scope :category, ->(category_id) {where(category_id: category_id).order(created_at: "DESC")}

さらに .limit(10) を加えたい場合

controller
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メソッドを使うと
モデルの記述に条件を加えるだけ

model
scope :category, ->(category_id) {where(category_id: category_id).order(created_at: "DESC").limit(10)}

モデルに記載してあげることで コントローラの肥大を防ぐことができます。

controller
def index
    @ladies = Product.category(1)
    @men = Product.category(2)
    @home_appliances = Product.category(8)
    @hobbies = Product.category(6)
end

まとめ

条件式に名前を付けられるので、直感的なコードになる

修正箇所を限定することが出来る

コードが短くなる

コードの記述を整理することで様々な機能の追加が実現出来る時もあると思います。

fat-controllerにならないようにモデルで上手く定義しましょう!

参考資料

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?