I'm having a little difficulty understanding alias_method
/alias_method_chain
. I have the following code:
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
This does exactly what I want to it to - append "with a cherry on top" to the top of any form_for
call.
But my understanding is this isn't good code for a few reasons. Firstly, it won't chain in any other overrides of form_for(?)
so if I were to write a second form_for
method which appended "and yet another cherry on top", it wouldn't show. And secondly, alias_method
and alias_method_chain
are sorta outdated solutions, and I should be using self.included
& sending to the module instead.
But I can't get self.included
to call this form_for
method - it just keeps calling the parent one. Here's what I'm trying:
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)
My above solution works, but I have a suspicion it's the wrong way of doing things. If any ruby veterans could show me a more elegant way of doing this - and/or why the second solution isn't being called - I'd be appreciative.
When you monkey patch something you must redefine the method, because there's no super to inherit from (so you can't use the second code excerpt).
Copying the current method implementation and adding your own is just asking for trouble, so this is where alias_method comes in.
alias_method :form_for_without_cherries, :form_for
It actually creates a clone to the original method, which you can use instead of super. The fact that you can't chain monkey patches is not a bug, it's a feature.
The rails alias_method_chain method was indeed deprecated, but only because it was a poor idea from the start. However alias_method is a pure ruby method, and when used correctly can provide an elegant way of monkey patching your code, that's why I'm pretty sure it's not going away any time soon.