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/cache
I 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.