Rails3 ActiveSupport::Concern

RailsのActiveSupport::Concern


ActiveSupport::ConcernはRubyで機能拡張や共通で利用する部分を切り出し、module化するときによくやる方法である
self.included内の処理を簡潔にするための機能です


Rubyのみの機能で実装した場合


以下のようなコードがあるとします
このコードはこのmodule Mをincludeしたクラスにクラスメソッドmy_class_method及びmy_instance_methodを追加するものです


module M
def self.included(base)
base.extend ClassMethods
base.send(:include, InstanceMethods)
end

module ClassMethods
def my_class_method
puts "M:class_method"
end
end

module InstanceMethods
def my_instance_method
puts "M:instance_method"
end
end
end

これは次のように利用します


class MyClass
include M
end

MyClass.my_class_method # => M:class_method
MyClass.new.my_instance_method # => M:instance_method

ActiveSupport::Concern (Rails3.1まで)


ActiveSupport::Concernを利用すると以下のようになります


require 'active_support/concern' # Railsアプリ内なら不要
module M
extend ActiveSupport::Concern

module ClassMethods
def my_class_method
puts "M:class_method"
end
end

module InstanceMethods
def my_instance_method
puts "M:instance_method"
end
end
end

ActiveSupport::Concernをextendし、後はその内部にmodule ClassMethodsで定義したものがクラスメソッドとして利用できるようになり、同様にmodule InstanceMethodsで定義したものがインスタンスメソッドとして利用できるようになります


また、以下のようにRailsのコールバックもいれることができるようになります


module M
extend ActiveSupport::Concern

included do
before_filter :module_m_filter
end

module InstanceMethods
def module_m_filter
puts "hoge"
end
end
end

ActiveSupport::Concern (Rails3.2から)


さて先ほどのInstanceMethodsの部分ですが、includeで使うという性質から、そもそも不要な部分です
そのため、Rails3.2からmodule InstanceMethodsがあり、そこでインスタンスメソッドを定義している場合は
Deprecationとなりました
つまり、今後は以下のように記述する必要があります


module M
extend ActiveSupport::Concern

module ClassMethods # ここはそのまま
...
end

# module InstanceMethods <= ここも不要
def my_instance_method
puts "M:instance_method"
end
# end <= ここは不要

コミットログはこの箇所となります
https://github.com/rails/rails/commit/401393b6561adc1ce7101945163c9601257c057a#activesupport/lib/active_support/concern.rb

スポンサーサイト
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。