はじめに
Railsのソースコードにて
class Shirt < ActiveRecord::Base
scope :red, -> { where(color: 'red') } do
def dom_id
'red_shirts'
end
end
end
というコメントアウトを発見。
scopeの引数にブロックがあって、その中にメソッドが定義されている。初めて見る書き方だった。
調べてみても意外とどのような挙動をするのか書かれていないので、記事にしてみる。
第三引数のブロック内にメソッドを定義するとどうなるか
class Post < ApplicationRecord
scope :ids_less_than_five, -> { where('id < ?', 5) } do
def hoge
where(title: 'hoge')
end
end
end
このようなPostモデルがあったときに、以下のようなコードが書ける
Post.ids_less_than_five.hoge
=> #<ActiveRecord::Relation [#<Post id: 2, title: "hoge", body: "おはようございます", created_at: "2022-05-31 08:32:00.964692000 +0000", updated_at: "2022-05-31 08:32:00.964692000 +0000", user_id: 5>]>
つまり定義したスコープに対して、チェーンできるメソッドをブロック内に定義することができる。
以下のようにPostに対してhogeメソッドを使うことはできない。
Post.hoge
=> NoMethodError (undefined method `hoge' for Post:Class)
結論
- 定義したスコープにだけチェーンできるメソッドを作れる
- 小分けにクラスメソッドやスコープにした方が使い勝手がいいのであまり使い道がない??(使い道があったら教えてください、、)