Last Updated: February 25, 2016
·
5.489K
· taybenlor

Caching with Rails 3.2

Recently I've been doing a bunch of caching in one of our apps. After looking around everywhere I noticed that while there's lots of information out there - there's not much which is holistic.

I'm using Memcache because that seems to be the current rage. Have a look at this installation guide from Heroku. Rails also has a in-memory cache which you can use otherwise.

Most of the caching stuff you'll do will look something like this

Rails.cache.fetch "some_key" do
  something_complex
end

Basically it checks if something exists for that key, if it does it will return that thing from the cache - otherwise it will perform the block and save that. Relatively straightforward and quite neat. Look at the documentation.

The important thing is knowing when and where to cache. There's a Rails guide on it, but it's not very good. Heroku does a very quick, but good coverage of caching strategies.

Basecamp Next uses a neat view caching trick. Instead of having caches time out, they make the cache key fluid. This requires a scheme where nested models touch their parents, causing their timestamp to change, thus change the cache key. Then they nest caches within caches so that if one layer invalidates the next will still be mostly cached.

If you have expensive queries, you can also cache them either in the model or in the controller. Use low level caching for this.

If you're using JBuilder to keep your JSON neat and in viewlike structures (which you should be doing), you may be frustrated to find that there is currently no cache support. But it is coming soon - if you are from the future, it may already be a feature. Check this pull request. I've also merged rails/jbuilder master and that pull request, if you want it now, right here.
Note: this is on the bleeding edge, do not trust it.

Overall the general gist is to cache as much as you can, and to cache in many layers. My added wisdom is to be wary of caching too many little things, because sometimes your database and your ruby is faster than your cache (what a strange thought?).