Join the social network of Tech Nerds, increase skill rank, get work, manage projects...
 
  • Before and After Filters in Rails

    • 0
    • 2
    • 1
    • 1
    • 0
    • 0
    • 0
    • 0
    • 2.50k
    Comment on it


    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)

Sign In
                           OR                           
                           OR                           
Register

Sign up using

                           OR                           
Forgot Password
Fill out the form below and instructions to reset your password will be emailed to you:
Reset Password
Fill out the form below and reset your password: