rc3.org

Strong opinions, weakly held

How many controllers do you need in a Rails application?

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.

The 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?

4 Comments

  1. My presentation at RailsConf is in large parts going to be about the size and scope of controllers. I’ll get the slides online afterwards.

  2. 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.

    You can circumvent this problem entirely by using the url_for method in your application. It will generate the appropriate URL for a controller/action based on your routes.rb file.

  3. Henry Leparskas

    June 22, 2007 at 9:47 am

    Thanks. A much needed discussion.

    I’m still on my first rails app. Because I read the Pickaxe book first, I have an ‘admin’ controller because of authorization concerns. However, the stuff done in the admin controller is just the editing of models such as ‘people’, which could also be done in a controller called people. I find that it is a bit confusing at first.

  4. Yes, thanks for the discussion.

    I’m working on my first rails application, which is driven mostly by internally published content, but will also have a community aspect which will allow registered users to log in, have access to special content, comment, and even buy stuff.

    So far, I have two controllers, one for the backend (a CMS, essentially) and one that serves up the content.

    Since I’ll need to have a privilege-based structure for the public, would it be advisable to have a separate controller for public access (which seems like it would require duplicating some functionality)? Or should I try to integrate privileges into my existing display controller?

    Thanks for any help.

Leave a Reply

Your email address will not be published.

*

© 2024 rc3.org

Theme by Anders NorenUp ↑