ActiveSupport::Concernモジュール

参照元

ActiveSupport::Concern でハッピーなモジュールライフを送る | TECHSCORE BLOG

Active SupportはRuby on Railsコンポーネントであり、Ruby言語の拡張、ユーティリティ、その他横断的な作業を担っている。言語レベルで基本部分を底上げして豊かなものにし、Railsアプリケーションの開発とRuby on Railsそれ自体の開発を合理化する。

ActiveSupport::ConcernモジュールはActiveSupportの一部である。 あらかじめモジュールにActiveSupport::Concernをextendしておくことによって、特異メソッド(クラスメソッド)の追加機能を簡単に使えるようになる。

例えば、ひとつのモジュールに特異メソッド(クラスメソッド)とインスタンスメソッドを設定したい時がある。この場合、Loggerモジュールをincludeすると、クラスメソッドとしてlog_of_class_methodが、インスタンスメソッドとしてlog_of_instance_methodが使える。

module Logger
  def self.included(base)
    base.extend(ClassMethods)
  end
 
  module ClassMethods
    def log_of_class_method
      puts 'This is class method!!'
    end
  end
 
  def log_of_instance_method
    puts 'This is instance method!!'
  end
end

extend ActiveSupport::Concernを使うと、上の記述をもう少し簡潔にできる。

module Logger
  extend ActiveSupport::Concern
  
  module ClassMethods
    def log_of_class_method
      puts 'This is class method!!'
    end
  end
 
  def log_of_instance_method
    puts 'This is instance method!!'
  end
end


scopeをモジュールに設定した時も同じ。 「def self.included(base) ... end」とする部分を「included do ... end」とできる。

included に渡したブロックが LogicalDeleteScopes の include 元のコンテキスト(つまり Article クラスのコンテキスト)で実行される。

module LogicalDeleteScopes
  extend ActiveSupport::Concern
  included do
    scope :without_deleted, lambda{ where(deleted_at: nil) }
  end
end
 
class Article < ActiveRecord::Base
  include LogicalDeleteScopes
end