Rails Best Practices 1: Fat Model – Skinny Controller
01:35 PMDevelopment, Metodologies, RubyClaudio
Maintain a skinny controller is one of the most important things to increase the readability and testability of the code.
Let’s see some practices to move from the logic controller to the model.
1. Named Scope
In this first example we see how to use a named_scope to move the research methods in the model, simplifying the controller.
Suppose you have a controller where in the index method we extract the list of sedan cars and that of the station wagon.
The first implementation we can write is the following:
1 2 3 4 5 6 7 8 | class CarsController < ApplicationController def index @sedan_cars = Car.find(:all, :conditions => { :category => 'sedan' }) @wagon_cars = Car.find(:all, :conditions => { :category => 'wagon'}) end end |
Now, defining two named_scope in the Car model we can see how easier is to write the same index method of the controller:
1 2 3 4 5 6 7 8 9 10 11 | class Car < ActiveRecord::Base named_scope :sedan, :conditions => { :category => 'sedan' } named_scope :wagon, :conditions => { :category => 'wagon'} end class CarsController < ApplicationController def index @sedan_cars = Car.sedan @wagon_cars = Car.wagon end end |
The new version of the index method is also easier to test.
2. Model Association
In the second example I will show you how to use “model association” to simplify a create method.
Suppose we have a classic blog example where we create a new post associated to the current user.
The first implementation can be done is the following:
1 2 3 4 5 6 7 | class PostsController < ApplicationController def create @post = Post.new(params[:post]) @post.user_id = current_user.id @post.save end end |
Defining an has_many association between users and post inside the model we can simplify the create method as follows:
1 2 3 4 5 6 7 8 9 10 | class User < ActiveRecord::Base has_many :posts end class PostsController < ApplicationController def create @post = current_user.posts.build(params[:post]) @post.save end end |
3. Scope Access
Continuing the blog example, as we see in this third example we can simplify the edit method using a scope access.
In our method we want allow altering a post only if it belongs to the current user.
As usual, we can write an initial implementation:
1 2 3 4 5 6 7 8 9 | class PostsController < ApplicationController def edit @post = Post.find(params[:id) if @post.current_user != current_user flash[:warning] = 'Access denied' redirect_to posts_url end end end |
The optimization that can be done in this case is to simplify the method so if you edit a post that not belongs to the current user is raised an exception of type RecordNotFound.
Using the named scoped the entire method reduces to a single line of code:
1 2 3 4 5 | class PostsController < ApplicationController def edit @post = current_user.posts.find(params[:id) end end |
In the next post of this series devoted to the Rails Best Practices we will see other ways to simplify the logic controller and move more in the model.
Tags: Best Practices, ruby on rails

















Cool! Thanks.
[...] post from 2006 Skinny Controller, Fat Model, and a more recent – 2010 – post Rails Best Practices 1: Fat Model – Skinny Controller which talks about moving making the controller skinny. Related Posts:Building a Better Drop Down [...]
[...] consigliati: http://therailsway.com/2007/6/1/railsconf-recap-skinny-controllers http://blog.devinterface.com/2010/06/rails-best-practices-1-fat-model-skinny-controller/ http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model Tagged as: best practice, [...]