我理解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)
我上面的解决方案是有效的,但我怀疑这是错误的做事方式。如果任何一位ruby老手能向我展示一种更优雅的方法,以及/或为什么没有调用第二个解决方案,我将不胜感激。
当你对某个东西进行猴子补丁时,你必须重新定义方法,因为没有super可以继承(所以你不能使用第二个代码摘录)。
复制当前的方法实现并添加自己的方法只会带来麻烦,所以这就是alias_method的用武之地
alias_method :form_for_without_cherries, :form_for
它实际上创建了一个原始方法的克隆,您可以使用它来代替super。事实上,你不能链猴子补丁不是一个错误,这是一个功能。
rails-alias_method_chain方法确实遭到了抨击,但这只是因为它从一开始就不是一个好主意。然而,alias_method是一个纯ruby方法,如果使用得当,可以提供一种优雅的方式来修补代码,这就是为什么我确信它不会很快消失。