Можно ли вызвать метод класса из ActiveRecord::Concern, не смешивая его с другим классом?
Я создаю ActiveSupport::Concern, который определяет несколько методов класса, используя class_methods
метод. С обычным модулем можно вызывать методы класса напрямую, используя NameOfModule.target_method
(например, в классе Math stdlib обычно вызывается acos, например, Math.acos(x)
) но я затрудняюсь найти способ выполнить аналогичный вызов мой Concern
, Возможно ли это, если да, то как?
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