Override rails helpers with access to original

独自空忆成欢 提交于 2019-11-28 09:00:48

There's a better way than any of your listed options. Just use super:

module AwesomeHelper
  def stylesheet_link_tag(*sources)
    if @be_awesome
      awesome_stylesheet_link_tag *sources
    else
      super
    end
  end
end

Overriding stylesheet_link_tag in AwesomeHelper will ensure that, when stylesheet_link_tag gets invoked, Ruby will encounter it in the method lookup path before it hits ActionView::Helpers::AssetTagHelper. If @be_awesome is true, you get to take charge and stop things right there, and if not, the call to super without parentheses will transparently pass through all the arguments up to the Rails implementation. This way you don't have to worry about the Rails core team moving things around on you!

I don't use this gem, so I'll answer you in a more generic way.

Let's say you want to log calls to link_to helper (yeah, contrived example, but shows the idea). Looking in API gives you understanding that link_to located inside the ActionView::Helpers::UrlHelper module. So, you create some file in your, say, config/initializers directory with the following contents:

# like in config/initializers/link_to_log.rb
module ActionView::Helpers::UrlHelper

    def link_to_with_log(*args, &block)
        logger.info '**** LINK_TO CALL ***'
        link_to_without_log(*args, &block) # calling the original helper
    end

    alias_method_chain :link_to, :log
end

The core of this functionality -- alias_method_chain (clickable). Use it AFTER defining the method xxx_with_feature.

Try using alias_method:

module AwesomeHelper
  alias_method :original_stylesheet_link_tag, :stylesheet_link_tag

  def stylesheet_link_tag(*sources)
    if @be_awesome
      awesome_stylesheet_link_tag *sources
    else
      original_stylesheet_link_tag *sources
    end
  end
end

I would really encourage you to consider your option #2, overriding the behavior of rails methods in a way that is obvious to the caller.

Your new method should be called awesome_stylesheet_link_tag so that other Rails devs can read your code and ask the question "What is so awesome about the link tag?".

As a smaller change you could do the override but pass in :awesome => true as an argument so they at least have a clue that something is afoot.

Changing the behavior of a widely used method like stylesheet_link_tag creates a potential future misunderstanding where none is needed.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!