Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
616 views
in Technique[技术] by (71.8m points)

ruby - Override rails helpers with access to original

I want to use rails' familiar helpers, but with slightly altered functionality. The way I see it, I want to be able to do something like:

module AwesomeHelper
  #... create alias of stylesheet_link_tag to old_stylesheet_link_tag
  def stylesheet_link_tag(*args)
    if @be_awesome
      awesome_stylesheet_link_tag *args
    else
      old_stylesheet_link_tag *args
    end
  end
end

The way I see it, I have three options:

  1. Monkey patching: Reopening the rails helper module. If the rails team ever change the name of their helper module, my code becomes a source of brittleness. Not insurmountable, but not ideal.
  2. Use different method names: Trying to stick to the common rails interface may be my downfall. My changes may become a source of confusion for other developers
  3. Detaching methods (new): Not sure whether this would work, or whether it would have the same drawbacks as 1. Will research this, but this might be a good starting point.

So the question here is, am I stuck with one of these sub-optimal solutions, or is there another way that I haven't considered? If I go for option 3, is there a way to do it without directly addressing the rails helper module?

(Note: I have removed the context, as it adds nothing to the question.)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...