Filtering Cached Pages with Action Caching

Problem

Page caching is fast because cached content is served up directly by your web server. Rails is not involved with requests to page-cached content. The downside is that you can't invoke filters, such as authenticating user requests for restricted content. You're willing to give up some of the speed of page caching to invoke filters prior to serving cached content.

Solution

Action caching is like page caching, but it involves Rails up until the point at which an action is rendered. Therefore, Rails has an opportunity to run filters before the cached content is served. For example, you can cache the contents of an area of your site that should be accessible only to administrative users, such as sensitive reports.

The following ReportsController demonstrates how you could set up action caching alongside page caching, to allow filters to be run before the cached content is served:

class ReportsController < ApplicationController
 before_filter :authenticate, :except => :dashboard
 caches_page :dashboard
 caches_action :executive_salaries
 def dashboard
 end 
 def executive_salaries
 end 
 private
 def authenticate
 # authentication code here...
 end 
end

In this example, the authenticate filter should run before every action except for dashboard, which contains public reporting that should be available to all users. The executive_salaries action, for example, requires authentication and therefore uses action caching. Passing the action name to the caches_action method makes this happen.

Discussion

Internally, action caching uses fragment caching with the help of an around filter. So if you don't specify a fragment store, Rails defaults to using the MemoryStore fragment store. Alternatively, you can specify FileStore in environment.rb with:

ActionController::Base.fragment_cache_store =
 :file_store, %W( #{RAILS_ROOT}/public/fragment_cache)

Although both page caching and action caching cache the entire content of the response, action caching invokes Rails Action Pack, which allows filters to run. Because of this, action caching will always be slower than page caching.

See Also