A little while ago I was ranting about rails controllers, and a bit after
that about @ivars in views. More recently I realised you can do
class ActionHandler < Module; end and I’ve been wondering what one could usefully do
with that.
This morning I had yet another scenario where I was adding three extra methods
to a controller so that one action method could be nicer. None of the other actions
would ever use those 3 methods. And as usual there were @ants in my @pants,
causing the proverbial itch which, according to legend, gives rise to open source.
“Separate controller” says my Refactor Pedant who sits on my right shoulder (my left shoulder being occupied by my Cowboy Coder).
And I thought “Hmm. Well, why not just put them in a module?”
And presently the following code emerged:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | |
So in a nutshell, you define the action method in the controller using the handle :owner
call, which does two things (What!? A method that does TWO things!?!? EEEeeeek. Run awaaaaay…):
- defines the
ownermethod so that rails will have a method to call and a default view to render - when the action method is called, include the defined methods in the current instance of the controller.
So now, in the view, you can refer to project and owner instead of @project and
@owner. Yes, the accessor for @owner will overwrite the owner action method.
Eww and Aahh and uuuuh! Well whaddya expect when you have to work around framework
stinkiness!?
In short, a way to get rid of name clashes in the controller, get rid of @ivars in views, and use that wacky inheriting from Module thing. Not bad, eh?
And it would be easy to iterate through all public methods defined in the handler block and add them as helper_methods. Making them automatically available in the view.