Thursday, 26 April 2012

Rails: Power to the filters


Rails: Power to the filters

Rails before_filters in controllers can help you keep your code DRY.
I have coded cases where all action functionality was included in 2-3 before_filters.
I’ll try to showcase some of the methods that work for me.

Authentication

The most commonly used before_filter should be that of authentication, and since this is global you can place it in you ApplicationController.
01.class ApplicationController < ActionController::Base
02.session :session_key => '_fortytwo_session_id'
03. 
04.before_filter :fetch_logged_user
05. 
06.def authenticate
07.unless @logged_user
08.#unauthorized access
09.redirect_to login_url, :status => 401
10.return false
11.end
12.end
13. 
14.def fetch_logged_user
15. 
16.unless session[:user_id].blank?
17.@logged_user = User.find(session[:user_id])
18.end
19. 
20.rescue ActiveRecord::RecordNotFound
21.end
22. 
23.end
Now, in every action, in every controller we have a @logged_user object. If it’s not nil , then we have an authenticated user.
So if we want to restrict access to authenticated users in a certain controller for some actions, we just need a before_filter for the authenticate function.
1.class UsersController < ApplicationController
2.before_filter :authenticate:except => :login
3.endre

CRUD Operations

Models usually have the common CRUD actions (new, edit, update, delete, create), and some other actions that operate on a specific model record. If you add authentication and probably authorization (only the owner of a blog post can change his content for example), things can get complicated. Unless…
01.class BlogController < ApplicationController
02.#authenticate is in our ApplicationController
03.before_filter :authenticate:except => :show
04.before_filter :fetch_post:only => [:show:edit:update:delete]
05.before_filter :authorise_as_owner:only => [:edit:update:delete]
06. 
07.private
08. 
09.def fetch_post
10.@post = Post.find(params[:id])
11.rescue ActiveRecord::RecordNotFound
12.#there is no such post
13.flash[:alert] = "Got lost?"
14.redirect_to error_url, :status => 404
15.return false
16.end
17. 
18.def authorise_as_owner
19.unless @post.user_id == @logged_user.id
20.#You don't belong here. Go away.
21.flash[:alert]  = "Mind your own business"
22.redirect_to error_url, :status => 401
23.end
24.end
25. 
26.end
If you are using roles, you can extend the authorisation behaviour (so that admins can edit any post) like this:
1.def authorise
2.unless @post.user_id == @logged_user.id || @logged_user.is_admin?
3.#You don't belong here. Go away.
4.flash[:alert]  = "Mind your own business"
5.redirect_to error_url, :status => 401
6.end
7.end
http://www.fortytwo.gr/blog/6/Rails-Power-to-the-filters

No comments:

Post a Comment