This page documents my favorite way of handling page caching with Rails and Passenger. It’s a simple and elegant technique if cache invalidation is infrequent and you can afford to sweep the entire cache once it happens. I’d appreciate any feedback on this article – just contact me.
Use cache_page or caches_page in your controllers.
public/cacheI don’t like polluting the public directory of my Rails applications with cache files so I dedicate a public/cache directory for them. Add this to your application configuration:
config.action_controller.page_cache_directory = "#{Rails.root}/public/cache"
Note: Replace Rails.root with RAILS_ROOT if you’re running an old version of Rails.
class CacheSweeper < ActiveRecord::Observer
observe YourModel, YourSuperModel
def self.sweep_cache!
pattern = "#{ActionController::Base.page_cache_directory}/**/*.html"
Dir.glob(pattern) do |filename|
File.delete(filename)
end
end
def after_save(*_)
self.class.sweep_cache!
end
def after_destroy(*_)
self.class.sweep_cache!
end
end
Activate this observer with config.active_record.observers or invoke CacheSweeper.sweep_cache! yourself. Please note that it sweeps the entire cache.
RailsAllowModRewrite On
RewriteEngine On
RewriteCond %{THE_REQUEST} ^(GET|HEAD)
RewriteCond %{REQUEST_URI} ^/([^.]+)$
RewriteCond %{DOCUMENT_ROOT}/cache/%1.html -f
RewriteRule ^/[^.]+$ /cache/%1.html [QSA,L]
RewriteCond %{THE_REQUEST} ^(GET|HEAD)
RewriteCond %{DOCUMENT_ROOT}/cache/index.html -f
RewriteRule ^/$ /cache/index.html [QSA,L]
Use RewriteLogLevel and RewriteLog if you need to troubleshoot mod_rewrite.
ActionController::Caching::Sweeper was replaced with ActiveRecord::Observer.define_method stuff was replaced with plain methods.