使用包含 class 同名方法的模块扩展 class

extending class with modules containing class methods of the same name

我通过 here and here 中描述的显着模式扩展了我的 ActiveRecord class。 我找不到一种方法来安全地让我新包含的 class 方法(extend_with_mod_aextend_with_mod_b)调用它们自己的 class 方法(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

输出是

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

当然,调用哪个栏方法取决于 ActiveRecord 包含调用顺序。我想在 extend_with_mod_a 方法定义

中使用类似 ModA::ClassMethods.bar 的东西

尝试: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