So you found yourself in the need to override a method but still count on it’s old behaviour?
No problem! Override it with your new code, call super and…. Uh oh!! Suddenly this turned into a problem… Let me give some more context.
I was testing Ferret (and the acts_as_ferret
plugin) in a project to provide full text search capabilities to our
models. One of the things the plugin does is to add a new method to
ActiveRecord, called find_with_ferret. That way, every model can use it. Great!
So I thought that would make sense for me to remove all diatrictics from the input text before letting ferret do its job. You know, like removing umlauts and all that.
I could do that by overriding this method with code to remove the
undesired chars and then call its older version to finally do the
search - something like calling super, but not quite. And I didn’t want
my models to inherit from anything else than ActiveRecord::Base. That
wouldn’t make any sense.
alias_method to the rescue!
You know that to redefine a method in an existing class you can open
it up and rewrite it. But since you don’t wanna loose the behaviour
provided by the original method, this is how you can achieve this:
module ActiveRecord
class Base
alias_method :find_with_ferret_original, :find_with_ferret
def find_with_ferret(q, options = {}, find_options = {})
remove_diatrictics!(q)
find_with_ferret_original(q, options, find_options)
end
end
end
And you’re good to go. On line 3 you’re just giving the original method an alias, making a copy of it.
Then you redefine it the way you like and on line 6 you call the old version to make sure u still got the same behaviour.
Now all my models can benefit of this change without requiring them to call another method nor inherit from another class.
Cool, huh?