我正在尝试编写一个通用模块,将方法创建模式应用于我的一些Rails模型。这些模型具有类方法和实例方法。虽然我可以相当直接地为一个类案例编写一个模块:
module ClassVersion
extend ActiveSupport::Concern
module ClassMethods
def method_missing(meth, *args, &block)
if meth.to_s =~ /^(.+)_async$/
Async::handle_async self, $1, *args, &block
else
super meth, *args, &block
end
end
# Logic for this method MUST match that of the detection in method_missing
def respond_to_missing?(method_name, include_private = false)
Async::async?(method_name) || super
end
end
end
或实例案例:
module InstanceVersion
extend ActiveSupport::Concern
def method_missing(meth, *args, &block)
if meth.to_s =~ /^(.+)_async$/
Async::handle_async self, $1, *args, &block
else
super meth, *args, &block
end
end
# Logic for this method MUST match that of the detection in method_missing
def respond_to_missing?(method_name, include_private = false)
Async::async?(method_name) || super
end
end
......我似乎无法在同一个班级支持这两种情况。有没有更好的方法来覆盖method_missing,以便支持这两种情况?我在Rails 3.2 ....
答案 0 :(得分:8)
你想要达到的目标非常简单,同时又不同寻常。 ActiveSupport::Concern
使您可以定义嵌套ClassMethods
模块,该模块正在included
模块挂钩上扩展基类。通常这很方便,因为您不希望使用相同的方法扩充类及其实例。
您需要做的是停止使用ActiveSupport::Concern
并编写included
挂钩以满足您的特定需求:
module AsyncModule
def method_missing(meth, *args, &block)
if meth.to_s =~ /^(.+)_async$/
Async::handle_async self, $1, *args, &block
else
super meth, *args, &block
end
end
# Logic for this method MUST match that of the detection in method_missing
def respond_to_missing?(method_name, include_private = false)
Async::async?(method_name) || super
end
private
def self.included(base)
base.extend self
end
end
答案 1 :(得分:0)
您是否尝试过以下
module ClassAndInstanceVersion
extend ActiveSupport::Concern
def method_missing(meth, *args, &block)
self.class.method_missing(meth, *args, &block)
end
def respond_to_missing?(method_name, include_private = false)
self.class.respond_to_missing?(method_name, include_private)
end
module ClassMethods
def method_missing(meth, *args, &block)
if meth.to_s =~ /^(.+)_async$/
Async::handle_async self, $1, *args, &block
else
super meth, *args, &block
end
end
# Logic for this method MUST match that of the detection in method_missing
def respond_to_missing?(method_name, include_private = false)
Async::async?(method_name) || super
end
end
end