#Modelのscopeとは?
Modelのscopeとは「共通のクエリの処理を設定し、それをメソッドのように使えるようにする機能」です。
例えば、下記のように公開日に達した記事だけを取り出すとします。
class ArticlesController < ApplicationController
def index
@articles = Article.where("published_date < ?", Time.now())
end
end
この公開日に達した時だけ取り出すという処理は何度も出てくるかもしれません。このときこの処理を共通処理としてまとめます。
class ArticlesController < ApplicationController
def index
@articles = Article.published
end
end
class Article < ApplicationRecord
scope :published, -> { where("published_date < ?", Time.now()) }
end
このように、.publishedをメソッドの要領で使うことが出来て便利です。
これがModelのscopeです。
#Modelのscope使い方
上記にもあるように基本は
class ArticlesController < ApplicationController
def index
@articles = Article.published
end
end
class Article < ApplicationRecord
scope :published, -> { where("published_date < ?", Time.now()) }
end
のようにmodelにscopeを記述して使います。
##引数を渡す
例えば、以下のようにある日時以降の記事を取り出したいとします。
class ArticlesController < ApplicationController
def index
@articles = Article.where("published_date >", time)
end
end
下記のように引数を渡せます。
class ArticlesController < ApplicationController
def index
@articles = Article.published_after(Time.now())
end
end
class Article < ApplicationRecord
scope :published_after, -> (time){ where("published_date >", time) }
end
##scopeをmergeする
下記のように複数のscopeをマージすることが出来ます。
class ArticlesController < ApplicationController
def index
@articles = Article.published.published_after(Time.now())
end
end
class Article < ApplicationRecord
scope :published_after, -> (time){ where("published_date >", time) }
scope :published, -> { where(published: true) }
end
##defaultのscopeを設定する
defalut_scopeを使うと設定したModel内の全ての検索クエリにおいてそのscopeが適用されます。論理削除のときなどに使えます。
class ArticlesController < ApplicationController
def index
@articles = Article.published_after(Time.now())
end
end
class Article < ApplicationRecord
default_scope :published, -> { where(published: true) }
scope :published_after, -> (time){ where("published_date >", time) }
end
##アソシエーションを使うときにscopeを設定する
以下のように設定するとアソシエーションを使うときにscopeを適用できます。
class Article < ApplicationRecord
has_many :comments, -> { order("updated_at DESC") }
end
この場合、commentsを更新日の新しい順に並べ替えます。
lambda ~->って何?~
->はlambda(ラムダ)記法で無名関数のような役割を果たします。
下記のRubyのコードを見るとどういう役割をしているか見えてきますね。
test = {
hoge: ->(x) { x + 2 }
}
puts test[:hoge][3] # 5
#参考
Rails ModelのScope(スコープ)の使い方(scopeメソッドとdefault_scopeメソッド)
Rubyのlambdaは無名関数では!?と気付き、調べた結果