RailsのActiveSupport::Concernで何が行われているか
ActiveSupport::Concern を使わない場合の concern の書き方について、公式ドキュメントをみながら、何が行われているのか見てみました。
デフォルトでは rails はapp/{controllers,models}/concerns
を自動で読み込むモードになっているのでConcerns::
のような名前空間をつける必要はありません。(参考: 公式ドキュメント)
concern の使い方としては読み込み先のクラスで、include M
でモジュールを読み込むと、included do..end
の中のメソッドがインスタンスメソッドまたはクラスメソッドとして読み込まれます。
インスタンスメソッドならdef sum ... end
、クラスメソッドならdef self.sum ... end
また、class_methods
に書いたメソッドはクラスメソッドとして拡張されます。
これをどうやって実現しているか見ていきます!!
ActiveSupport::Concern
を使う場合、使わない場合、を記載して使わない場合のコードについて一つづつ見ていきます!
require "active_support/concern"
module M
extend ActiveSupport::Concern
included do
scope :disabled, -> { where(disabled: true) }
end
class_methods do
...
end
end
module M
def self.included(base)
base.extend ClassMethods
base.class_eval do
scope :disabled, -> { where(disabled: true) }
end
end
module ClassMethods
...
end
end
こちら、公式ドキュメントよりモジュールを読み込んだ時に発動するメソッドだと解ります。
つまり、include M
とするとこのクラスメソッドが読み込み先のクラスで発動しbase
には読み込み先のクラスが入ってきます。
読み込み先のクラスであるbase
がClassMethods
というモジュールを拡張して、ClassMethods
に書いてあるメソッドをbase
がクラスメソッドとして使えるようになります。
base
に中のインスタンスメソッドまたはクラスメソッドを追加しています。
ちなみに、scope
はクラスメソッドと同じように振る舞いますがif
のような条件文を使う場合は注意が必要なようです。
今回の記事は以上になります!読んでいただいてありがとうございます!
解りにくいところ、間違っているところなどあれば連絡いただければと思います。
何か連絡をしたい際は以下 SNS、メールでお願いいたします。
Twitter: https://twitter.com/naka_ryo_z