简体   繁体   中英

extending class with modules containing class methods of the same name

I extended my ActiveRecord class by the notable pattern described here and here . I can't find a way to safely make my new included class method ( extend_with_mod_a and extend_with_mod_b ) call their own class method ( bar )

require 'active_record'

module ModA
  extend ActiveSupport::Concern

  module ClassMethods

    def extend_with_mod_a
      puts "extending #{self} with ModA"
      bar
    end

    def bar
      puts "this is method bar of ModA"
    end

  end

end


module ModB
  extend ActiveSupport::Concern

  module ClassMethods

    def extend_with_mod_b
      puts "extending #{self} with ModB"
      bar
    end

    def bar
      puts "this is method bar of ModB"
    end

  end

end

ActiveRecord::Base.send :include, ModA
ActiveRecord::Base.send :include, ModB

class TestModel < ActiveRecord::Base

  extend_with_mod_a
  extend_with_mod_b

end

Output is

extending with ModA
this is method bar of ModB
extending with ModB
this is method bar of ModB

Of course which bar method gets called depends on ActiveRecord include calls order. I would like to use something like ModA::ClassMethods.bar in extend_with_mod_a method definition

尝试:prepend在模块:prepend

ActiveRecord::Base.send :prepend, ExtModule
module ModA
  extend ActiveSupport::Concern

  module ClassMethods
    def bar
      puts "this is method bar of ModA"
    end

    # grab UnboundMethod of ModA::ClassMethods::bar
    a_bar = instance_method(:bar)

    # using define_method to capture a_bar
    define_method :extend_with_mod_a do
      puts "extending #{self} with ModA"
      # invoke ModA::ClassMethods::bar properly bound to the class being extended/included with ModA
      a_bar.bind(self).call
    end
  end
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM