These days it seems to be conventional wisdom to build “skinny” controllers in your Rails app. Skinny controllers help you to consolidate your business logic into one place (the model) which allows for easier maintenance and testing. If you’re still not convinced, perhaps you should watch this informative public service announcement.
I’ve been using the excellent resource_controller plugin by James Golick for well over a year now. Its an excellent tool for handling the standard RESTful controller actions that one normally codes by hand (or generator.) We currently use it in the Spree project and yesterday I was curious to compare the size of these controllers to those of a project that does not use resource_controller. First lets look at the results of running rake stats on the Spree project.

As you can see, there are 44 controllers in this project. Yeah, that’s a lot of controllers but Spree is a pretty huge project (its a full featured e-commerce platform.) Now notice that out of 44 classes we only have 111 methods. That’s an average (rounding down) of only 2 methods per class! The methods themselves are also pretty skinny with an average of 8 lines of code per method.
Now lets take a look at Fat Free CRM. I chose this project because it is similar to Spree in that its a full featured platform (not just a little plugin.) DISCLAIMER: I’ve never used this application but I’ve heard good things about it. I’m in no way trying to disparage another person’s work here – I just need a point of comparison.

You can see that this project’s controllers are pretty fat. There are only 12 of them but they have more lines of code then in the 44 controllers of Spree. There are 11 methods per controller (compared to 2 in Spree), with the typical method size being the same as Spree. Don’t let the equivalent method size fool you. For instance, take a look at this typical 4 line method in a Spree controller.
create do
flash nil
wants.html {redirect_to edit_order_url(@order)}
end
This is an example of how we override the default resource_controller behavior. In this specific case we did not want to include anything in the flash, nor redirect to show after object creation. If you’re happy with the resource_controller defaults, this method is not even needed.
If you’re interested in a thorough overview of resource_controller, Fabio Akita has produced a very detailed screencast on how it works. Its one of the longest screencasts I’ve ever seen (about 1 hr) but its well worth the time if you’re struggling to wrap your head around how REST works in Rails (both with and without resource_controller.)
Tags: resource_controller
I switched from resourcecontroller to the MUCH better and more Ruby-ish “inheritedresources”:
http://github.com/josevalim/inherited_resources
resourcecontroller is for controllers what RSpec is for tests, while inheritedresources is for controllers what Shoulda is for tests. I.e. if you don’t like bloated “my little pony”-DSL:s that do magical stuff that’s hard to control, I would go with inheritedresources that relies on standard subclassing and no new DSLs but still at least as dry as resourcecontroller – but makes more sense to a pure Rubyist. That’s why I switched, I want to have control and I love the Ruby syntax. Don’t invent a new DSL:s just because it’s cool to write DSL:s…that’s not cool.
I started playing with this back in Feb 08 and have always thought this is how rails should work out of the box. I especially like the haml support. It surprises me that more folks are using this great plugin. Nice writeup.
Pesonally, I don’t like how things are done with resource controller. It’s just not obvious.
My personal thanks to Michael Dvorkin of FFCRM for not using it.
How does performance compare on a controller with resource_controller versus explicit method implementations?
Inherited resources sounds interesting. I’ll definitely check it out. The rspec to shoulda analogy has me interested (as I just recently made that switch.) I don’t think resource_controller was invented just for the sake of inventing a DSL. It solves a major problem for me. That said, I’m always open to a better way of doing things.
I have no information on the performance of resource_controller. I can’t imagine there would be a noticeable difference but I’m only guessing.
grimen: Maybe inherited_resources looks better but it has a major drawback. It haven’t worked for me because of using inheritance.
I have got common AdminController < ApplicationController scenario which stops me from using this plugin. resourcecontroller works great. Correct me if I’m wrong and there is a way of using inheritedresources with inherited controllers – I’ve only played with it for a couple of minutes.
@grimen – Funny thing is that rspec relies on standard Ruby subclassing and shoulda does not. Perhaps a new analogy?
I see a bulk of code written in the library. And your models are even skinnier than controllers. I am not sure why, but once we added a service layer in the lib that took care of many business logics. Using this we had skinny controllers, but it was no good. Because the business logic still got split into models and lib, which was difficult to manage/refactor/test. Another thing is, the best value of putting business logics in models is not achieved unless unit test is used. I see a very small number of unit tests. Do you follow any other method for testing your business logic?
@Sohan – We’re moving in the direction of adding more unit tests. We recently started using Factory Girl and Shoulda which have eased the burden of writing them. All new features are added with unit tests and we’re slowly adding unit tests retroactively as well.
Sean, thanks for running the numbers, it’s quite interesting!
I had considered using the resourcecontroller, but decided to go with plain REST. My primary reasons: 1) resourcecontroller seems to hack too deep into Rails internals, so it’s a dependency that is likely to cause potential problems with new Rails releases; 2) code clarity — with plain REST I feel like it’s quite clear what’s going on; 3) testing — it’s not obvious how you’re supposed to write specs when using resource_controller.
I guess at the end of the day it’s a matter of personal taste