我对alias_method
/ alias_method_chain
的理解有点困难。我有以下代码:
module ActionView::Helpers
module FormHelper
alias_method :form_for_without_cherries, :form_for
def form_for(record, options = {}, &proc)
output = 'with a cherry on top'.html_safe
output.safe_concat form_for_without_cherries(record, options = {}, &proc)
end
end
end
这正是我想要的 - 在任何form_for
电话的顶部追加“顶部有一个樱桃”。
但我的理解是,由于一些原因,这不是好的代码。首先,它不会链接到form_for(?)
的任何其他覆盖,所以如果我要编写第二个form_for
方法,其中附加“而另一个樱桃在顶部”,它将不会显示。其次,alias_method
和alias_method_chain
是过时的解决方案,我应该使用self.included
&而是发送到模块。
但我无法让self.included
调用此form_for
方法 - 它只是一直调用父方法。这是我正在尝试的:
module CherryForm
def self.included(base)
base.extend(self)
end
def form_for(record, options = {}, &proc)
output = 'with a cherry on top'.html_safe
output.safe_concat super(record, options = {}, &proc)
end
end
ActionView::Helpers::FormHelper.send(:include, CherryForm)
我的上述解决方案有效,但我怀疑这是错误的做事方式。如果任何红宝石老兵能够向我展示一种更优雅的方式 - 和/或为什么没有调用第二种解决方案 - 我会很感激。
答案 0 :(得分:4)
当你修补某些东西时,你必须重新定义该方法,因为没有超级继承(所以你不能使用第二个代码摘录)。
复制当前的方法实现并添加自己的方法只会遇到麻烦,所以这就是alias_method的用武之地。
alias_method :form_for_without_cherries, :form_for
它实际上为原始方法创建了一个克隆,您可以使用它而不是super。你无法链接猴子补丁的事实不是一个错误,它是一个功能。
rails alias_method_chain方法确实已被弃用,但这只是因为从一开始就是一个糟糕的主意。然而alias_method是一种纯粹的ruby方法,如果使用正确可以提供一种优雅的猴子修补代码方式,这就是为什么我很确定它不会很快消失。