Skip to content
PLAY VIDEO PLAY VIDEO PLAY VIDEO
By Aaron Beckerman

If you explicitly expire cached fragments, opt out of cache digests

We upgraded a Rails 3 application to use Rails 4, and found that certain pages weren’t being updated as we expected. The problem was that cached fragments were no longer being expired properly.

The problem

Briefly: The application was explicitly expiring cached fragments by name. After the upgrade to Rails 4, this code didn’t have the intended effect because the templates were creating different fragment names; the application was no longer expiring the fragment names that the templates were actually using.

Let’s look at this in more detail. In Rails 3, you could have a template with this code:

<% cache 'hello' do %>
  ...
<% end %>

This would cache the fragment in the block under a name derived from your argument. In this example, we supplied the argument “hello” and the name generated would be “views/hello”.

Elsewhere in your application, you could explicitly expire that fragment, so that the next time the fragment was referenced, it would be regenerated. You’d do that by sending this message to a controller object:

expire_fragment('hello')

This would generate the full name, “views/hello”, and expire the cached fragment with that name.

Say we start using Rails 4. Now the caching code in the template appends a new piece of information – a cache digest – to the fragment name it generates. The cache digest will depend on the current template and its dependencies. In our example, the fragment name might be something like “views/hello/e3225f7c7bbadd41c6ea556b7b7a03b1”.

The code that expires the fragment, however, is outside the context of this template, so it does not know the cache digest. As with Rails 3, it will try to expire the fragment named “views/hello” – but that’s not what our fragment is called anymore. The fragment, then, is no longer being expired.

Solutions

How do we fix this?

Well, ideally, the application wouldn’t be expiring fragments explicitly. Instead of a string literal, the template would pass a relevant object as the argument to cache, and that object would generate its own cache key. The code for generating the key would be carefully designed so that the key would only change if the object changed in such a way that it might need to be presented differently.

But you go to war with the code you have, not the code you wish you could have. If the application will continue to expire fragments explicitly, then one simple solution is to stop appending the cache digest. We found every fragment we were trying to explicitly expire and passed the option :skip_digest => true to cache. So the template code looked like this:

<% cache 'hello', :skip_digest => true do %>
  ...
<% end %>

This solved our problem – well enough for the time being, at least.

By the way: If you ran into this problem during a Rails upgrade, the addition of cache digests created some inconvenience for you. Don’t get annoyed, though. This is, in fact, a very cool feature of Rails 4: cache digests allow for Russian doll caching.

Latest Articles by Our Team

Our expert team of designers and developers love what the do and enjoy sharing their knowledge with the world.

We Hire Only the Best

reinteractive is Australia’s largest dedicated Ruby on Rails development company. We don’t cut corners and we know what we are doing.

We are an organisation made up of amazing individuals and we take pride in our team. We are 100% remote work enabling us to choose the best talent no matter which part of the country they live in. reinteractive is dedicated to making it a great place for any developer to work.

Free Community Workshops

We created the Ruby on Rails InstallFest and Ruby on Rails Development Hub to help introduce new people to software development and to help existing developers hone their skills. These workshops provide invaluable mentorship to train developers, addressing key skills shortages in the industry. Software development is a great career choice for all ages and these events help you get started and skilled up.

  • Webinars

    Webinars

    Webinars are our online portal for tips, tricks and lessons learned in everything we do. Make the most of this free resource to help you become a better developer.

    Learn more about webinars

  • Installfest

    Installfest

    The Ruby on Rails Installfest includes a full setup of your development environment and step-by-step instructions on how to build your first app hosted on Heroku. Over 1,800 attendees to date and counting.

    Learn more about Installfest

  • Development Hub

    Development Hub

    The Ruby on Rails Development Hub is a monthly event where you will get the chance to spend time with our team and others in the community to improve and hone your Ruby on Rails skills.

    Learn more about Development Hub

Get the “reinteractive Review” Monthly Email