alias_method, alias_method_chain, and self.included



我理解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_methodalias_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方法,如果使用得当,可以提供一种优雅的方式来修补代码,这就是为什么我确信它不会很快消失。

相关内容

  • 没有找到相关文章

最新更新