Rails Best Practices 6: Filters and helpers file
12:30 PMDevelopment, Metodologies, RubyClaudio
With the today’s post I shall conclude my series on Ruby On Rails Best Practices . This is not because the required topics are completed, but rather because after the release of Rails 3.0, some constructs have been changed and should be reviewed.
Probably in future we will return to talk about best practices, but starting from the new features introduced in the current Rails version.
But now I will describe two techniques that are valid and which are mainly related to code organization.
1. Use filters
In order to remove duplicate code within the controller is good practice to use the filters to perform tasks that are common to most if not to all methods.
A classic case in which you use filters is user authentication.
Another example may be a function that makes the log of user activity.
I show here a very simple example for demonstration purposes only
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | class ApplicationController < ActionController::Base def add_log #create new log log = ActivityLog.new # read data from request log.session_id = request.session_options[ :id] log.user_id = current_user.id log.browser = request.env['HTTP_USER_AGENT'] log.ip_address = request.env['REMOTE_ADDR'] log.controller = controller_name log.action = action_name log.request_at = Time.now # Save the log log.save end #other methods here end |
We have defined our function add_log that saves data request in a log on db.
Now in our controller we will do something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | class PostController < ApplicationController def index add_log @posts = Post.all end def new add_log @post = Post.new end def show add_log @post = Post.find(params[ :id] end def edit add_log @post = Post.find(params[ :id] end def create add_log @post = Post.create(params[:post] end def update add_log @post = Post.update(params[:post] end def destroy add_log @post = Post.find(params[ :id] @post.destroy end end |
The PostController can be optimized using a before_filter in the following way
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | class PostController < ApplicationController before_filter :add_log def index @posts = Post.all end def new @post = Post.new end def show @post = Post.find(params[ :id] end def edit @post = Post.find(params[ :id] end def create @post = Post.create(params[:post] end def update @post = Post.update(params[:post] end def destroy @post = Post.find(params[ :id] @post.destroy end end |
Then if we want the calls to some methods (eg show and index) can not be traced we can simply define the filter as follows:
1 2 3 4 5 | class PostController < ApplicationController before_filter :add_log, :except => [:show, :index] # methods |
Obviously the use of filters should be done in a careful way because excessive use of before_filter or after_filter for operations not so general can make the code less immediate to understand.
2. Organize helpers by functionality
The second technique that I introduce today is a better system (in my opinion) to organize helper files.
Rails typically generates an helper file for each controller. So it’s easy that in a short time you have a large number of helpers and often you use only a few of them.
For example:
1 2 3 4 5 | app/helpers/application_helper.rb app/helpers/comments_helper.rb app/helpers/posts_helper.rb app/helpers/users_helper.rb # ... |
And in the ApplicationController:
1 2 3 | class ApplicationController < ActionController::Base helper :all # include all helpers, all the time end |
A system I find very convenient is rather to organize helpers for functionality, removing all unnecessary and empty files.
1 2 3 | app/helpers/application_helper.rb app/helpers/buttons_helper.rb app/helpers/treeviews_helper.rb |
In the ApplicationController you not need to change anything. As before it loads all the helpers in the helpers folder. The advantage of this solution is to have fewer helper files and know immediately where to enter or search for a method when you have to add or change it.
Tags: after_filter, before_filter, Best Practices, helpers, rails, ruby on rails

















[...] This post was mentioned on Twitter by Hugo Roque, DevInterface. DevInterface said: "Rails Best Practices 6: Filters and helpers fileRails Best Practices 6: Filtri e file helper" – http://bit.ly/djxFTA #rubytweets [...]
There’s a lot of controller code that should be in a model:
class ApplicationController < ActionController::Base
def add_log
ActivityLog.log_access(self, request)
end
#other methods here
end
class ActivityLog request.session_options[ :id],
:user_id => controller.current_user.id,
:browser => request.env['HTTP_USER_AGENT'],
:ip_address => request.env['REMOTE_ADDR'],
:controller => controller.controller_name,
:action => controller.action_name,
:request_at => Time.now,
})
end
end
</code.