When it comes to Ruby on Rails style, one of the toughest decisions to make is how many controllers you need. The default custom for Rails seems to center around having one controller per model, but that doesn’t always make the most sense.
To discuss this at a high level for a moment, models generally mirror the structure of the database, so there’s one model per table. Controllers are arbitrary collections of actions, but are usually associated with a particular model, so if you have a model called “posts” in a weblog application, you might have a controller called “posts” as well, with actions like list posts, new post, edit post, and so forth. This was generally the pattern I followed when I started creating Rails applications, but increasingly I’m finding there are other ways to group functionality in controllers that make more sense.
For example, one alternate form of organization is grouping functionality by the rights required to use it. In the Rails Recipes book, there’s a recipe for an authorization system that is based on controllers and actions. Grouping actions into controllers based on privilege makes that system easier to apply to an application. For example, I have an admin controller that has all of my actions that are only for administrators, regardless of which model they pertain to, and a feeds controller that requires no authorization at all.
Rails in many ways works like other Web application frameworks that I’ve used before, but the grouping of functionality into controllers is a new way of organizing things to me. In PHP you generally have one template per action (unless you play games with the query string to reuse templates), and with Java frameworks like Struts and Spring, you have one big configuration file for your application and then one “controller” for each action. You could certainly follow either of those patterns in Rails, but it would be ungainly.
Another criteria I use when deciding whether a new controller is needed is URL cleanliness. We added some personalization features to our application, so we created a new controller called “my”. The URLs based on that controller are things like “/my/watchlist”, “/my/contributions”, and “/my/reviews”. They’re very easy to read and remember. All of those actions could just as easily be in another controller associated with a model, but breaking them out made sense to me.
routes.rb file also comes into play when it comes to making decisions about controllers. You can use it to manipulate URLs in any way that you choose, but as a general rule I prefer to do as little URL hacking as possible and instead stick with the default structure of Rails applications. Using
routes.rb, you could use many controllers and make your application look like you use only one or vice versa. Doing so would make things hard on developers, though, because then you lose the default mapping of URLs to controllers and actions, and it becomes harder to map URLs within your application to locations in your code. I prefer to avoid that.
For the other Rails developers out there, are there any rules of thumb you apply when it comes to how many controllers you create?