Caching in Rails

In Rails we have two different ways of Caching

- Page Caching: which is always stored on Disk
- Action & Fragment Caching: which uses the configure cache configured in our Rails instance.

By default Rails provides three techniques:

1) Page Caching

Allows the request for a generated page to be fulfilled by the webserver, without ever having to go to your RoR application.

In other words if you have page caching turned on,  the request will come in, go to Mongrel, the page will then be generated, and then sends  it back to apache.  Additionally,  it will be stored in a local file system. Next time we request the same page, apache will load the page from the filesystem and send it back to the client, without your Rails application being called at all.

To turn on page caching you need to make sure  “perform_caching” is set to true for your environment.  This flag is normally set in the corresponding config/environments/*.rb

By default, caching is disabled for development and test, and enabled for production.

config.action_controller.perform_caching  = true

The next step is to cache the action(s) in the controller by using the page-caching approach that will store the cache in a path.

caches_page :index, :show

Page Cache options

We can cache any  filesystem format (json, xml, iphone) by using the Rails response format.

The page caching mechanism will automatically add the appropriate corresponding extensions: /public/users.html; public/users.xml; public/users.json; public/users.iphone.

By default it gets cached under public/<name>.html. Changing the default helps avoid naming conflicts, since we put static html in public/. To do this, it will require web server reconfiguration to let the web server know from where to serve the cached files .

Rails::Initializer.run do |config|
   config.action_controller.page_cache_directory = "#{RAILS_ROOT}/public/cache"
...
end

Quick Tips

Page caching ignores all parameters, so if your request is http://mysite.com/users?page=1, it will be written out as public/users.html.  A request like http://mysite.com/users?page=3, will be served as users.html. To avoid this you might consider  changing your routes.rb

2) Action Caching

Action caching works like page caching except that the incoming web request goes from the web server to the Rails apps. It does this so that before_filters can be run before the cache file is served. This allows you to use authentication and other restrictions while still serving the results of the request from a cached copy.

We want to use action caching while running “filters” or executing code in the views, but remember the content is always the same. So in your controller you will call :

caches_action   :show

before_filter :autenticate, :only => [:show]

Action Caching Options

You can set different ways of cachings in /config/environments/development.rb

config.cache_store = :file_store, ‘tmp/cache’
config.cache_store = :memory_store, which basically is {} in memory (background).
Note:
- You can run out of memory
- There no sharing between processes. You cannot use it if you run more than one instance of your rails apps.

Including different options such as:config.cache_store = :mem_cache_store

share apps: config.cache_store = :mem_cache_store, :namespace => “store”
multiple servers: config.cache_store = :mem_cache_store, 192.168.1.255:1001, 192.168.1.255:1002
config.cache_store = :drb_store
  • as custom_store

config.cache_store = :drb_store

To use action caching, add the method caches_action: <action> to your Controller

Features

1. Cache the action without the layout.

class PostsController < ApplicationController
    caches_action :index, :show
    before_filter :autenticate, :only => [:show], :layout => false
 .......
end

It will only cache your action content. Note: If you need some sort of data you might want to use before_filter and set you instance variables.

2. Conditional Action action using :if (or :unless) => Proc.new{….} to specify when the action should be cached.

3. Specific path using :cache_path => Proc.new { |controller| ….} or
:cache_path => {:expires_in =>1.hour }, to specify when the action should be cached. (only with memcached & rails > 2.1)

3) Fragment Caching

Fragment caching allows you to fragment many pieces of the view. The pieces will be wrapped in a cache block and served out of the cache store when the next request comes in. Fragment caching is useful for dynamic web applications.

When the same request comes in again, we pull the different pieces out of the cache, combine them into a single page, and send it back to the client.

To implement fragment caching, cache your method  in the view:

<% cache (:recent_joined) do %>
    <% @recent_joined.each do |user| %>
.........
    <% end %>
<%end>

And you will see the fragment key in the log, which are prefixed with “views/”

Post a Comment

Your email is never shared. Required fields are marked *

*
*