Rails Best Practices 1: Fat Model – Skinny Controller

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: ,


About Claudio

Claudio Marai is a co-founder of DevInterface.

After graduating in Computer Science has contributed to develop complex web applications based on Java/J2EE and desktop applications with the. NET framework for the Ministry of Justice and ultimately for the banking ambit.

The passion for web in recent years has led him to be interested in more modern frameworks such as Ruby on Rails and Django, and to a development approach based on agile methodologies such as eXtreme Programming and SCRUM.

About DevInterface

We are an information and communication technology agency. Our mission is to provide web application development, design services and communication strategies. We specialize in building web applications with modern and efficient frameworks.

Related Post

3 Responses to “Rails Best Practices 1: Fat Model – Skinny Controller”

  1. Tenorio says:

    Cool! Thanks.

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

Leave a Reply

Insert code beetween <code lang="ruby"> and </code>

Copyright 2012 DevInterface s.n.c.

DevInterface Blog is proudly powered by WordPress