Reputation: 2226
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:
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.)
Upvotes: 25
Views: 12007
Reputation: 15129
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
Upvotes: 6
Reputation: 3780
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.
Upvotes: 2
Reputation: 3181
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!
Upvotes: 40
Reputation: 15771
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
.
Upvotes: 5