Join the social network of Tech Nerds, increase skill rank, get work, manage projects...
 
  • Basic Caching in Rails

    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 279
    Comment on it

    What exactly is caching and how do rails try to achieve it. Well basically rails provide us with an automatic caching feature which help us in increasing the speed of our site by reducing the amount of time consumed by making frequent call to either database or controllers for the same piece of data.

    On a high level rails provide us with 3 types of caching :

    1) Page caching
    2) Action caching
    3) Fragment caching

    To make use of rails caching feature it need to be enabled in respective files like development.rb,staging.rb etc. By default caching is turned off for development environment. To enable caching just make the following change in respective file :

    config.action_controller.perform_caching = true

    Page Caching

    It is a mechanism where rails store cached controller action in a file format. By default all the cached pages are stored in public folder. In order to achieve page caching we have to follow the following approach :

    class BlogsController < ApplicationController
      caches_page :index
      def index
        @blogs = Blog.all
      end
    end
    

    In this caches_page :index is the keyword used for caching the page which will be cached as blog.html in public folder. We seldom need to update cache when we either update or delete a record to achieve this we need to add the following code :

    class BlogsController < ApplicationController
      caches_page :index
      def  index
        @blogs = Blog.all
      end
      def create
        expire_page :action => :index
        @blog = Blog.new(params[:blog])
        @blog.save
      end
      def update
        expire_page :action => :index
        @blog = Blog.find(params[:id])
        @blog.update_attributes(params[:blog])
      end
    end
    

    Place where rails cached pages are stored can be changed using the following configuration option

    config.action_controller.page_cache_directory =

    Action Caching

    Action caching similar to page caching except that it is based on filters i.e certain conditions that need to be satisfied in order to access that page

    The syntax for doing action cache is :

    class BlogsController < ApplicationController
      before_filter :authenticate
      caches_action :index
      def index
        @blogs = Blog.all
      end
    end
    

    Only difference being caches_action :index in place of caches_page :index

    For making caching based on certain conditions for action cache we need to add the following conditions:

    class BlogsController > ApplicationController
      caches_action :index, :if => Proc.new{|c|!c.request.format.json?}
      def index
        @blogs = Blog.all
        respond_to do |format|
          format.html # index.html.erb
          format.json { render json: @blogs }
          format.csv
        end
      end
    end
    

    Fragment Caching

    Page caching and Action caching both cache entire web page for the user , what if there are small fragments that need to be cached separately for a particular page. To achieve this fragment caching came into existence which does not cache the entire page but try to cache page in small sections.

    Below is the example which shows fragment caching taking example of comments for a user :

    <div>
      <%= @blog.title %><%= @blog.desc %>
    </div>
    
    <%cache("blog_comments_#{@blog.id}") do%>
      <h3>Comments</h3>
      <% @blog.comments.each_with_index do|c, i|%>
        <div><%= c.value%><span><%= c.created_at.strftime('%B %d %Y')%></span></div>
      <%end%>
    <%end%>
    <%= link_to 'Add New comment', new_blog_comment_path(@blog)%>
    

    here comments are cached based on their id like "blog_comments_#{@blog.id}" i.e blog_comments_1 etc. If a user delete or update the comment we can update the cache using the following approach :

    class BlogsController < ApplicationController
      def create
        @blog = Blog.find params[:blog_id]
        expire_fragment("blog_comments_#{@blog.id}")
        @comment = @blog.comments.new(params[:comment])
      end
    end
    

    Although we have been using code in controller to expire cache but rails provide us with a better way of doing it based on the models which take care of when a record has been added or deleted to achieve this we make use of Sweepers.

    Sweepers are responsible expiring caches . They observe models and execute callbacks as defined in the sweeper.

    class BlogSweeper < ActionController::Caching::Sweeper
      observe Blog
      def after_update(blog)
        expire_action(:controller => :blogs, :action => :index)
      end
      def after_create(blog)
        expire_action(:controller => :blogs, :action => :index)
      end
    end
    

    All you need to do is call this sweeper in your controller as :

    class BlogController < ApplicationController
      cache_sweeper :blog_sweeper, :only => [:index]
    end
    

 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: