So I was going over the official documentation about Rails Concerns here and was trying to wrap my head around why their example of plain module mixin doesn't work, and how do Concerns solve this problem.
Why does the code below throw a NoMethodError?
Of course, I tried several approaches in the code on my end to try and comprehend the context, but I just cannot understand why the NoMethodError is being thrown within the self.extended hook in Bar.
module Foo
def extended(base)
base.class_eval do
def self.method_injected_by_foo
puts "Foo module"
end
end
end
end
module Bar
extend Foo
def self.extended(base)
puts "=== Acestors ==="
puts base.ancestors # [Host, Bar, Foo, ... , Object, ...]
puts "===== self ====="
puts self # Bar
puts self.methods.include?(:method_injected_by_foo) # true
puts "===== base ====="
puts base # Host
puts base.methods.include?(:method_injected_by_foo) # false
puts "================"
base.method_injected_by_foo # NoMethodError
end
end
class Host
include Bar
end
To my understanding, although the method_injected_by_foo doesn't exist within the Host class per se, it should be available in the next immediate ancestor (Bar) when looking up the ancestors chain, and call that method.