How to setup and use Rack::Cache with Rails 2.3
First install rack-cache:
1 sudo gem install rack-cache
Install Rails version 2.3 or greater:
1 sudo gem install rails
Or, freeze your project to Rails edge:
1 cd project 2 rake rails:freeze:edge
Add this to config/environment.rb:
1 config.middleware.use Rack::Cache, 2 :verbose => true, 3 :metastore => 'file:/var/cache/rack/meta', 4 :entitystore => 'file:/var/cache/rack/body'
Note the name is middleware, not middlewares which is used in all examples I found online, even the Rails blog.
Check the Rack configuration:
1 rake middleware
You should see something like this:
1 use Rack::Lock 2 use ActionController::Failsafe 3 use ActionController::Reloader 4 use ActionController::Session::CookieStore, #<Proc:0x00002b45ab39e3a8@(eval):8> 5 use ActionController::RewindableInput 6 use ActionController::ParamsParser 7 use Rack::MethodOverride 8 use Rack::Head 9 use Rack::Cache, {:metastore=>"file:/var/cache/rack/meta", :entitystore=>"file:/var/cache/rack/body", :verbose=>true} 10 use ActiveRecord::QueryCache 11 run ActionController::Dispatcher.new
Tell Rack to cache data by putting this in your controller:
1 expires_in 5.minutes, :public => true
Note that you should avoid caching private data when the user is signed in. In this case you should set the Cache-Control header to private or completely avoid using expires_in:
1 expires_in 5.minutes, :public => true if !signed_in?
Rails sets cache-control to private by default, Rack needs public content.
With verbose set to true, you’ll see this in the thin logs:
1 [cache] trace: cache miss 2 [cache] trace: fetching response from backend 3 [cache] trace: store backend response in cache (ttl: 300s) 4 [cache] trace: storing response in cache 5 [cache] trace: delivering response ... 6 [cache] trace: cache hit (ttl: 276s) 7 [cache] trace: delivering response ...
Note that ActionController::AbstractRequest has been renamed to ActionController::Request in Rails 2.3.0, so some plugins might throw this error in your face:
1 load_missing_constant': uninitialized constant ActionController::AbstractRequest
Problems
If you get one of these errors you need to change the way you require the rack-cache gem:
1 uninitialized constant Rack::Cache 2 3 uninitialized constant Rails::Rack::CacheI’ve found that this doesn’t work:
1 config.gem "rack/cache", :lib => 'rack/cache'
Instead, I’m requiring rack-cache by adding this to environment.rb:
1 require 'rack-cache' 2 3 4 Rails::Initializer.run do |config|
References
HTTP RFC – Cache-Control
Rack::Cache options documentation
Rails expires_in documentation