You need to extend the module with ActiveSupport::Concern
in order for the ActiveSupport::Concern#included
and #class_methods
methods to work properly.
These two methods are after all pretty much the only reason for its existance.
module A
extend ActiveSupport::Concern
# raises ArgumentError (wrong number of arguments (given 0, expected 1))
included do
puts "Hello World"
end
end
module B
extend ActiveSupport::Concern
included do
puts "Hello World"
end
end
class C
include B
end
# Outputs Hello World
Check out what happens if we inspect the included
method:
module AB
include ActiveSupport::Concern
puts method(:included).source_location # nil
end
module ABC
extend ActiveSupport::Concern
puts method(:included).source_location # .../ruby/gems/2.7.0/gems/activesupport-6.0.2.1/lib/active_support/concern.rb
end
When we extend the module with ActiveSupport::Concern
we are putting it on the ancestors chain of ABC
, thus the methods of ActiveSupport::Concern
are available as module methods of ABC
. This does not happen when you use include
and the included
method called is actually Module#included from the Ruby core.