Options
- HTTP Caching: Uses HTTP headers to instruct browsers on server side caching.
- Page Caching: Cache the entire page to disk and serve directly from the web server like Nginx.
- Action Caching: Runs through the rails pipeline and runs before_filters but returns cached results from disk like page caching.
- Fragment Caching: Store parts of views in the cache.
- Rails.cache: In memory server side cache.
Page Caching
class ProductsController < ActionController
caches_page :index
def index
@products = Products.all
end
end
/productswill generate a file called products.html.gz. NGINX will efficiently serve this static file- by default pages are cached in /public
To expire a page you call expire_page in the action that would invalidate the cache.
class ProductsController < ActionController
caches_page :index
def index
@products = Products.all
end
def create
expire_page :action => :index
end
end
Nginx can serve compressed content directly from disk by enabled gzip_static
location / {
gzip_static on;
}
Page caching ignores parameters like /products?page=1. If someone requests /products?page=2 they will get the cached first page. A workaround is to use a route like /products/page/1
Action Caching
This is good for pages that restrict access in some way. Incoming request does go from webserver to rails stack. Before filters are run to allow for things like authentication. Instead of expire_page you use expire_action.
class ProductsController < ActionController
before_filter :authenticate
caches_action :index
def index
@products = Product.all
end
def create
expire_action :action => :index
end
end
Fragment Caching
Add cache “key” to your view to cache a fragment. You can use the updated_at timestamp to signal when to invalidate the cache.
<%= cache "post-#{@post.id}", @post.updated_at.to_i do %>
<h1><%= @post.title %></h1>
<p><%= @post.content %></p>
<% end %>
If you touch a post it will update the timestamp.
Post.find(2).touch
class Comment < ActiveRecord::Base
belongs_to :post, :touch => true
end
Rails Cache
Rails.cache.write('foo', 'bar')
Rails.cache.read('foo')
Rails.cache.clear