Search code examples
ruby-on-railsrubyactivesupportactivesupport-concern

ActiveSupport::Concern methods not found


I am extending ActiveRecord::Base. In my lib folder, I have a file mongoid_bridge.rb:

module MongoidBridge
  extend ActiveSupport::Concern
  module ClassMethods
    ...
  end
  module InstanceMethods
    ...
    def create_mongo(klass, fields)
      ...
    end
  end
end

ActiveRecord::Base.send(:include, MongoidBridge)

In config/initializers, I have two files, in order to be read in the correct order, each is prefixed with 01, 02, etc. In 01_mongo_mixer.rb, I have the following:

require "active_record_bridge"
require "mongoid_bridge"

Then in 02_model_initializer.rb, I have the following:

MyActiveRecordModel.all.each do |model|
  model.create_mongo(some_klass, some_fields)
end

model is an instance of an ActiveRecord subclass, so it should find create_mongo instance method in the lookup chain. However, it does not find it, as I get the following error:

Uncaught exception: undefined method `create_mongo' for #<MyActiveRecordModel:0x007fff1f5e5e18>

Why can't it find the instance method?

UPDATE:

It seems that methods under ClassMethods are included, but not the methods under InstanceMethods:

singleton_respond = MyActiveRecordModel.respond_to? :has_many_documents
# => true
instance_respond = MyActiveRecordModel.new.respond_to? :create_mongo
# => false

Solution

  • You don't need an InstanceMethods module - your module should look like

    module MongoidBridge
      extend ActiveSupport::Concern
      module ClassMethods
      ...
      end
    
      def create_mongo
      end
    end
    

    Earlier versions of rails made use of an instance methods module but in the end it was decided that this was redundant since you could just define the methods in the enclosing module. Using InstanceMethods was deprecated a while back (maybe rails 3.2 - my memory is fuzzy) and subsequently removed