我是否可以从ActiveRecord :: Concern调用类方法而不将其混合到另一个类中?

时间:2016-08-03 01:47:30

标签: ruby-on-rails ruby activesupport-concern

我创建了ActiveSupport::Concern,使用class_methods方法定义了几个类方法。使用常规模块,可以直接使用NameOfModule.target_method调用类方法(例如,在stdlib类中,数学通用调用acos就像这样Math.acos(x))但是我&# 39;我不知道如何执行类似的调用my Concern。这是可能的,如果是的话,怎么样?

1 个答案:

答案 0 :(得分:1)

不,您不能,因为class_methods块中定义的方法实际上是在模块Foo::ClassMethods中定义的(Foo是您的关注点)。以下是ActiveSupport::Concern

的相关源代码
module ActiveSupport
  # ...
  module Concern
    # ...
    def class_methods(&class_methods_module_definition)
      mod = const_defined?(:ClassMethods, false) ?
        const_get(:ClassMethods) :
        const_set(:ClassMethods, Module.new)

      mod.module_eval(&class_methods_module_definition)
    end
  end
end

您可以看到class_methods只是为您创建模块ClassMethods,如果它不是您自己定义的。您定义的方法只是该模块中的实例方法,因此您无法在模块级别调用它。

稍后,模块ClassMethods将由包含您关注的类扩展。以下是相关的源代码:

module ActiveSupport
  # ...
  module Concern
    def append_features(base)
      if base.instance_variable_defined?(:@_dependencies)
        # ...
      else
        # ...
        base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods)  # <-- Notice this line
        # ...
      end
    end
  end
end