Filter in Rails
Filters are the methods, that run before, after or around a controller action. We can better understand it by taking an example. Suppose in a blogging site, there are groups and we want that a user can only read blogs of his group. So we can place a before filter there and thus every request for blog view will go to that method first (which will check the user for authorization) and if it returns true, then only it will go to the requested action otherwise it will be redirected to somewhere else as given in the method.
Filters follow the inheritance, so if a filter method is defined in ApplicationController, it will run on every controller in action. There are 3 kinds of filters available in rails:
before_action : In versions prior to 4.0 before_filter is used that is not even deprecated, you can use any
after_action : In versions prior to 4.0 after_filter is used that is not even deprecated, you can use any
around_action : In versions prior to 4.0 around_filter is used that is not even deprecated, you can use any
As I already explained the use case of before_action, lets directly see, how it works:
class ApplicationController < ActionController::Base
before_filter :authenticate_user
private
def authenticate_user
unless is_part_of_group?
flash[:error] = "You are not a member of requested group"
redirect_to home_page_url # halts request cycle
end
end
def is_part_of_group?
if params[:group_id] == user.group_id
return true
else
return false
end
end
end
In the above example, we can see if a user wants to view a blog that is not of his group, the method in before_filter will set a flash error message and the user will be redirected to homepage.
As we can see here the authenticate will call before each action. We can also skip it for some actions or can use it with specific actions. Example:
class BlogsController < ApplicationController
skip_before_filter :authenticate_user, :only => [:new, :create]
end
Thus the before_filter will not be called for new and create acions of blog controller. You can also use :except method, that is just opposite to what :only does.
after_filter or after_action, as its name suggests, it runs after the action is completed like responding the data. As an example, if we want to render json for app requests and html for web request, after_filter is best to use.
around_action or around_filter are used for running their associated actions by yielding, similar to how Rack middlewares work. Thus it might have logic before and after the action being run. It simply yields to the action in whatever place is necessary. You can also use around filters for exception handlings:
class ChangesController < ActionController::Base
around_filter :catch_exceptions
private
def catch_exceptions
yield
rescue => exception
logger.debug "Caught exception! #{exception}"
raise
ends
end
In addition to these there are more ways of using filters. One method is to use a block directly to the *_filter. It receives controller as an argument and the authenticate_user filter from above could be rewritten to use a block as:
class ApplicationController < ActionController::Base
before_filter do |controller|
redirect_to home_page_url unless controller.send(:is_part_of_group?)
end
end
One more way of applying filter is by using a class. It is mainly useful in complex cases where filters can't be implemented using other methods in a reusable and readable way. Here I am taking the same previous example just to make you understand of how to write filter in this way.
class ApplicationController < ActionController::Base
before_filter BlogViewFilter
end
class BlogViewFilter
def self.filter(controller)
unless controller.send(:is_part_of_group?)
controller.flash[:error] = "You are not a member of requested group"
controller.redirect_to controller.home_page_url
end
end
end
Hope you liked this blog. For more Blogs on Rails, Click here.
0 Comment(s)