Always Pass a Block When Using alias_method_chain
Posted by Larry Karnowski Fri, 29 Aug 2008 15:00:00 GMT
If you're using Rails' alias_method_chain mechanism, please make sure that your new method always takes a block and passes that block up the chain, even if you don't need the block yourself. Consider this being a good "alias_method_chain" neighbor. Here's why -- if you don't, no one who comes along behind you can add a block to the chain. You've effectively "block-blocked" them.
Here's an example. I wanted to add some functionality to Rails' error_messages_for method. Specifically, I wanted to be able to pass a block to it that implemented a tiny DSL for massaging the errors output before passing them up the chain to the normal error_messages_for functionality. I implemented this by adding an alias_method_chain layer on top of the error_messages_for.
In my tests this worked fine, but when I put it in my actual Rails project, the method just stopped working. It took me a while to find that another developer on the project was also alias_method_chaining the error_messages_for, but was not taking a block, and thus not passing it up the chain. In effect, he was dropping my block on the floor. No good.
So here's the template you should follow when creating an alias_method_chain:
def method_with_something_cool(arg1, arg2, &block) ... your custom pre-chain code ... method_without_something_cool(arg1, arg2, &block) ... your custom post-chain code ... end alias_method_chain :method, :something_cool
Call the old method with a block even if the old method never took a block! Don't be a cock-blocker! Err.... block-blocker!
