Applying the agent nouns are code smells rationale, nicely worded by my colleague Peter Gillard-Moss, controllers are code smells. The more I look at REST and the more I look at how MVC gets typically mapped to it, the more I think the C in MVC is doing the wrong thing, even when it’s skinny as possible.
I’ve only come across very few and extremely limited cases where I need to do more in a Rails or Merb controller than simply delegate to the model and set some options about how the resource is going to be represented. Most of this code can be inferred by simply looking at the available routes and methods on the model, essentially making them declarative statements rather than fully capable objects that encapsulate some behaviour of my system, or coordinate inputs and outputs.
In fact, in a RESTful application where simple and CRUD-like behaviour is encouraged in (or even expected from) all resources of the domain, controllers are just plain unnecessary. If you’ve tried something like CrudTemplate, resources_controller or resource_controller, that’s the sort of thing I’m talking about… only without the the controller as a class.
Sinatra gets this right by doing away with the controllers and allowing you to tie blocks of code to URL matchers. Still, opportunity makes the thief, and allowing a block of code to decide what’s going to be rendered or what models get called is still going to put developers in a position where they have to fight to keep their control code skinny, while moving as much functionality as possible into a rich domain model. It’s fighting an incredibly difficult battle, since the refactoring weapons are just not powerful enough at the moment, and might never be. I’d prefer declarative statements: what, not how.
Because declarative, ladies and gentlemen, is good.