我有一个类方法,我希望模块重载,这样模块方法可以调用super或其他方式来调用原始类的实现。这类似于alias_method_chain,但问题是:是否可以通过ActiveSupport :: Concern实现这一点?
请考虑以下事项:
module CustomAction
CUSTOM_ACTIONS = {custom_action_one: "c1", custom_action_two: "c2"}
include ActiveSupport::Concern
module ClassMethods
def find(id)
CUSTOM_ACTIONS[id] || super
end
end
end
class Action
include CustomAction
ACTIONS = {action_one: "1", action_two: "2"}
def self.find(id)
ACTIONS[id]
end
end
因此,您可以在此处看到CustomAction类正在添加操作,并希望重载/覆盖默认的#find操作,以便它首先在自定义操作中查找,如果它在那里找不到,则会回退到原始查找实施。
然而,这不起作用。始终会调用原始实现。即使您在原始#find。
的定义之后添加了include,也是如此我试图避免使用alias_method_chain,因为1)是不是已经过时了?哪里ActiveSupport :: Concern是新的热点2)它需要在实现下面放置包含有点奇怪
思想?
答案 0 :(得分:0)
您不能使用ActiveSupport :: Concern来覆盖类方法,因为ActiveSupport :: Concern使用(ActiveSupport::Concern source code):
base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods)
与:
相同 class Action
extend CustomAction::ClassMethods
end
因此,您应该使用prepend,在Action单个实例之前插入CustomAction :: ClassMethods。结果是:
module CustomAction
CUSTOM_ACTIONS = {custom_action_one: "c1", custom_action_two: "c2"}
module ClassMethods
def find(id)
CUSTOM_ACTIONS[id] || super
end
end
end
class Action
ACTIONS = {action_one: "1", action_two: "2"}
def self.find(id)
ACTIONS[id]
end
#prepend on the Action single instance , not on the instance
class << self
prepend CustomAction::ClassMethods
end
end