Rails Subdomain Caching
OCT
02
2009
A while ago, I was working on a site that had dynamic subdomains based on cities in the database. For example, if an admin created a record for Nashville, it would create http://nashville.sitename.com. The site was pretty content heavy, but didn't change a whole lot, so I wanted to cache as much as I could. The problem with caching was that the content of each page depended on the subdomain. I couldn't use the normal caching strategy because of this.
To handle the subdomain routing and identification, I used the awesome subdomain-fu plugin (which worked great). Subdomain-fu, however, does not do the work of putting your cached files into folders named for your subdomain. Luckily, fixing this was as easy as adding a before filter to my ApplicationController.
class ApplicationController < ActionController::Base
before_filter :update_cache_location
def update_cache_location
if current_subdomain.nil?
ActionController::Base.page_cache_directory = "#{RAILS_ROOT}/public/cache/"
else
ActionController::Base.page_cache_directory = "#{RAILS_ROOT}/public/cache/#{current_subdomain}/"
end
end
end
That method will update the page_cache_directory value to be your current subdomain (or default if you are on the main domain). Now, this takes care of one problem, but how the hell do we retrieve the cached files? I had a little bit of trouble with this, mainly because I'm not a mod_rewrite specialist. After some tinkering and testing, I finally came up with the following rules to put in my conf file to properly retrieve the cached files based on the subdomain.
# Check for subdomain cached index
RewriteCond %{HTTP_HOST} !^www\.sitename\.com
RewriteCond %{HTTP_HOST} ^([^.]+)\.sitename\.com
RewriteRule ^/$ /cache/%1/index.html [QSA]
# Check for subdomain cached page
RewriteCond %{HTTP_HOST} !^www\.sitename\.com
RewriteCond %{HTTP_HOST} ^([^.]+)\.sitename\.com
RewriteRule ^([^.]+)$ /cache/%1/$1.html [QSA]
# Check for regular non-subdomain index
RewriteRule ^/$ /cache/index.html [QSA]
# Check for regular non-subdomain page
RewriteRule ^([^.]+)$ /cache/$1.html [QSA]
Those first two entries check to make sure the subdomain isn't www, then checks the cache folder for a cached version of the page. The last two entries check for the regular www subdomain.
These entries worked great for my project, but, like I said, I'm no expert with mod_rewrite. If you see anything that can be simplified or a better way of doing something, please let me know in the comments.
Tagged: rails, caching, tutorial
@Matt: Thanks for pointing that out. I forgot that I had added a before_filter to my ApplicationController to deal with that. I've updated the post to include the code I used.
Leave a comment:
Popular Posts
Search
Tags
actionmailer activerecord ajax apache apple barcamp caching capistrano centos code golf css db delete eager loading ebay email attachment erb flash ftp fun generators get haml helpers ie sucks javascript jquery lightbox lost merb net ftp paperclip passenger php plexus post presentation rails rails machine railsconf redesign rest rjs routes rss ruby ruby on rails safari script sinatra symfony text replacement tips tutorial twitter xhtml
Projects
© 2010 Travis Roberts. All rights reserved.
Matt said on March 19, 2010:
As far as I can tell, subdomain-fu doesn't seem to separate cached requests by subdomain. I had to manually do it using method described here: http://launchpad.rocketjumpindustries.com/posts/5-defining-a-dynamic-page-cache-loction-by-subdomain-in-rails