我正在尝试从另一个rails引擎中装饰一个控制器。我有一个控制器方法,我想扩展只有一行。我宁愿不复制整个原始控制器方法。
这就是我的尝试:
Backend::BaseContentsController.class_eval do
def booking_update
# do some stuff
update
end
alias_method :update, :booking_update
end
不幸的是,这会引发异常stack level too deep
。通常继承我可以称为超级。在我的情况下,做什么是理想的?
答案 0 :(得分:6)
您应该尝试alias_method_chain
:
def update_with_booking
# do some stuff
update_without_booking # that's your old update
end
alias_method_chain :update, :booking
答案 1 :(得分:2)
您已定义无限递归。结果是以下代码段。
def update
# do some stuff
update
end
确保您的别名不会覆盖您仍在使用的方法。
Backend::BaseContentsController.class_eval do
alias_method :update_original, :update
def booking_update
# do some stuff
update_original
end
alias_method :update, :booking_update
end
答案 2 :(得分:2)
module Decorator
def update
# do some stuff
super
end
end
Backend::BaseContentsController.prepend(Decorator)
答案 3 :(得分:0)
说明:
在同一方法上同时使用alias_method和Module#prepend stack level too deep
时发生错误。
当同时使用这两个方法时,它们都会尝试查找实际定义,但会获取其他定义,现在它们都试图将其定义放在堆栈顶部,这会导致太多的堆栈条目并产生stack level too deep
错误。
解决方案:
避免使用alias_method和alias_method_chain,因为它们已被弃用。为此,请使用 Module#prepend 代替这些。 Module#prepend已在Ruby 2.0中添加
参考:
https://blog.newrelic.com/engineering/ruby-agent-module-prepend-alias-method-chains/ https://docs.newrelic.com/docs/agents/ruby-agent/troubleshooting/systemstackerror-stack-level-too-deep https://ethigeek.com/blogs/mutually-exclusive-alias-method-and-prepend