Rails Best Practice: Fat Model, Skinny Controller

November 18th, 2011 Leave a comment Go to comments

This is one of the most important (yet often ignored) best practices. Developers who are new to the Ruby on Rails platform tend to put more logic in the view. A very simplistic example follows.

View

<% posts = Post.find (:conditions => "deleted = ‘N’", :order => "created_at") %>
<table>
<% posts.each do |post| %>
<tr>
<th>Title</th>
<td><%= post.title %></td>
<th>Since</th>
<td><%= (Time.now - post.created_at) / 1000 %>
</tr>
<% end %>
</table>

The problem here is that all the logic has been pushed into the view. As a result, the code is very difficult to read and maintain. The more fundamental issue here is that the MVC (Model-View-Controller) principle is compromised because logic code is mixed in with the view. A better approach would be to put the logic in the controller. The controller can be programmed as follows:

Controller

class PostsController < ActionController
def index
@ posts = Post.find (:conditions => "deleted = ‘N’", :order => "created_at")
end
end

View

<table>
<% @posts.each do |post| %>
<tr>
<th>Title</th>
<td><%= post.title %></td>
<th>Since</th>
<td><%= (Time.now - post.created_at) / 1000 %>
</tr>
<% end %>
</table>

Although, this solution is reasonably better than the original code, we can do even better. The view in this case is slightly more readable but it still contains logic to calculate the time elapsed since the post was created. We can improve the above design as follow:

Controller

class PostsController < ActionController
@posts = Post.active_posts
end
Model
class Post < ActiveRecord::Base
def since
(Time.now - post.created_at) / 1000
end
def self.active_posts
Post.find (:conditions => "deleted = ‘N’", :order => "created_at")
end
end

View

<table>
<% @posts.each do |post| %>
<tr>
<th>Title</th>
<td><%= post.title %></td>
<th>Since</th>
<td><%= post.since %>
</tr>
<% end %>
</table>

As you can see from the example above, not only all the logic has been pushed out of the view, but we have also managed to make the controller smaller and more readable by moving the conditions inside the model itself. Although the above example is very simplistic, it is not hard to see the impact this principle can make on code readability in read world applications.

  1. No comments yet.

Leave a reply

 
 
 


seven + = 14