Concernとは何か。どう便利なのか。
[Rails] ActiveSupport::Concern の存在理由 - Qiita で解説されている内容をもう少し初歩から説明してみる。
次のようにBase
があり、継承したSub1
, Sub2
があるとする。
class Base
# Baseのクラスメソッド
def self.hoge(str)
puts str
end
end
class Sub1 < Base
hoge("same")
end
class Sub2 < Base
hoge("same")
end
実行すると次のように表示される:
same
same
このSub1, Sub2の中の
hoge("same")
の部分がまったく同じなので、コピペでなく共通化したい。しかし普通にmoduleを使って
class Base
# Baseのクラスメソッド
def self.hoge(str)
puts str
end
end
module Mod
hoge("same")
end
class Sub1 < Base
include Mod
end
class Sub2 < Base
include Mod
end
と書くとundefined method `hoge' for Mod:Module
とエラーになってしまう。
正しくはincluded
を使って次のように書けば良い。
class Base
# Baseのクラスメソッド
def self.hoge(str)
puts str
end
end
module Mod
def self.included(base)
base.class_eval do
hoge("same")
end
end
end
class Sub1 < Base
include Mod
end
class Sub2 < Base
include Mod
end
これでちゃんと
same
same
と表示されるようになった。
この書き方がちょっと複雑だというので考えられたのがConcern。Concernを使うと次のように書ける。
require "active_support/concern"
class Base
# Baseのクラスメソッド
def self.hoge(str)
puts str
end
end
module Mod
extend ActiveSupport::Concern
included do
hoge("same")
end
end
class Sub1 < Base
include Mod
end
class Sub2 < Base
include Mod
end
Concernのもう1つのメリットとして、includeする側が依存関係を考えなくて済むという事もある。