ruby-on-railsrubyvisitor-statisticimpressions

Save requests for a certain action


I want to save information about requests to a certain action in a model named Impression.

I assume it's benificial for the visitor's response time to save this info in an after_filter, e.g:

after_filter :save_impression


private
    def save_impression
        Impression.create!(ip_address: request.remote_ip, controller_name: params[:controller], action_name: params[:action], referer: request.referer)
    end

Can this code be optimized or am I doing it right?


Solution

  • A good solution for that would typically involve using a worker. Anything that is not mission critical to the request and that involves complex computing can be deferred and run later by a background job.

    Two common implementations of workers are delayed_job and resque.

    For example, with resque, you would have a job class in app/jobs/impression_creation_job.rb, containing something like that :

     class ImpressionJob
      @queue = :impression
    
      def self.perform( attrs )
        Impression.create!( attrs )
      end
    end
    

    And you can call it in your controller like that :

    after_filter :save_impression
    
    
    private
      def save_impression
        Resque.enqueue( ImpressionJob, ip_address: request.remote_ip, controller_name: params[:controller], action_name: params[:action], referer: request.referer)
      end
    

    This will ensure a fast handling on the request part (it just loads data in redis) and will then be processed by a background process (see resque documentation for how to set it up and start workers).

    Please note that this will be useful in your case in only two cases :

    1. Your app is always under heavy load or need especially good response time
    2. You do big computations in Impression#before_create or other callbacks

    If not matching one of those conditions, it's probably more effective to just let your impression creation in a controller filter : accessing database has a cost, but not that much that a user will feel when you make a single insertion in database.