3

我有点难以理解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)

我的上述解决方案有效,但我怀疑这是错误的做事方式。如果任何红宝石老手可以向我展示一种更优雅的方式 - 和/或为什么不调用第二个解决方案 - 我将不胜感激。

4

1 回答 1

4

当您修补某些东西时,您必须重新定义该方法,因为没有可以继承的超级对象(因此您不能使用第二个代码摘录)。

复制当前的方法实现并添加你自己的只是自找麻烦,所以这就是 alias_method 的用武之地。

alias_method :form_for_without_cherries, :form_for

它实际上创建了原始方法的克隆,您可以使用它来代替 super。您不能链接猴子补丁的事实不是错误,而是一个功能。

rails alias_method_chain 方法确实被弃用了,但这只是因为它从一开始就是一个糟糕的主意。然而 alias_method 是一个纯粹的 ruby​​ 方法,如果使用得当,可以提供一种优雅的猴子修补代码的方法,这就是为什么我很确定它不会很快消失的原因。

于 2012-04-05T20:08:33.773 回答