Sunday, December 16, 2007

Utility Belt vs. Rails

Upgrade to Utility Belt 1.0.6 to avoid this Rails bugness: gem update utility_belt

This is kind of like a chiuhuahua taking on Godzilla - you might admire his pep but you already know how the story will end - but Utility Belt and Rails appear to be scuffling.

Orion Edwards e-mailed me about my last Utility Belt post, regarding the Rails bug:

here are my findings...

1) If you put 'require utility_belt' in your ~/.irbrc, then utility belt always gets loaded, even if you're not running irb
This is the rails bug you mention. ActiveSupport::Dependancies pulls it in, but I’ve no idea why

2) The file utility_belt/lib/interactive_editor.rb defines a method called 'edit' as an instance method under Object

3) class Class is inherited from Object, so this means that not only does every object have an instance method of 'edit', every class now has a class method of 'edit'

4) Rails marks all methods in ActionController::Base as hidden, and as hidden_actions is a class method of ActionController::Base, it applies to all controllers everywhere

5) This causes the 'edit' method to be marked as hidden. ‘edit’ is quite common in controllers

Your .rhtml template file will get called without the 'edit' in the controller ever running, so in 99% of cases, you'll get an error indicating your @item is nil.

There’s 3 fixes

1) not have utility belt in your .irbrc (boo)

2) edit the utility belt source to prevent it defining an 'edit' method on Object (I did this personally as I don’t use the interactive editor)

3) edit the utility belt source to call it ‘ed’ instead of ‘edit’ (or some other alternative)

Orion was in fact way ahead of me. I figured out the edit part of it, but I hadn't realized that hiding the controller methods would make the error messages weirder. His prediction about the @item being nil is correct - the first user to bring this to my attention, in his screencast, saw @id showing up as nil for no obvious reason.

I told Orion this and posted it in Raganwald's comments but I might as well reiterate it here - I am releasing a patch to Utility Belt which renames the method to avoid this bug in Rails, but what I really want to do is fix this bug in Rails. There's no logical reason for Rails to be loading your .irbrc unless it's running script/console. It's definitely a bug. So, although I will release a patch to UB very soon, long-term I'll be much happier if I find the bug in Rails and patch it, and long-term I think that's infinitely better for the community, since Utility Belt isn't the only piece of code out there that can go in your .irbrc, and weird bugs that are hard to track don't make life better for anyone.