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
owner
method 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.