Rails 4.0 expire_fragment/cache expiration not working

cache-expiration, caching, ruby, ruby-on-rails

Solution

I believe the issue is that when you cache the fragment in your view, a cache digest is being added to the cache key (views/all_available_releases/41cb0a928326986f35f41c52bb3d8352), but expire_fragment is not using the digest (views/all_available_releases).

If you add `skip_digest: true` to the cache call in the view it should prevent the digest from being used.

<% cache "all_available_releases", skip_digest: true do %>
 <% @releases.each do |release| %>
  <% cache(release) do %>
   <html code with>
   <%ruby code @release.name blah blah blah%>
  <%end%>
 <%end%>
<%end%>

Cache digests are only intended to be used with automatic cache expiration. If you need to manually expire cache keys then you can't use cache digests.

Problem

I have been trying to use the caching capabilities of rails, but I am unable to expire some cache fragment although they seem to expire. Using the 'Russian Doll Caching' as pointed out in the rails tutorial site, I am using this configuration ``` <% cache "all_available_releases" do %> <% @releases.each do |release| %> <% cache(release) do %> <html code with> <%ruby code @release.name blah blah blah%> <%end%> <%end%> <%end%> ``` I expire the outer caching in the release_controller.rb controller, where I use expire_fragment("all_available_releases") to expire the fragment. I use it in every method of the controller that updates or deletes or adds an entry. This is the log of WEBrick, where although the expire fragment gets registered, 5 lines later the expired fragment is read and used while it shouldn't. This example is after a destroy call. ``` Processing by ReleasesController#destroy as HTML Parameters: {"authenticity_token"=>"***/***/********************+********=", "id"=>"2"} Release Load (0.1ms) SELECT "releases".* FROM "releases" WHERE "releases"."id" = ? LIMIT 1 [["id", "2"]] (0.1ms) begin transaction SQL (2.0ms) DELETE FROM "releases" WHERE "releases"."id" = ? [["id", 2]] (148.0ms) commit transaction Expire fragment views/all_available_releases (0.1ms) Redirected to http://127.0.0.1:3000/releases Completed 302 Found in 180ms (ActiveRecord: 150.2ms) Started GET "/releases" for 127.0.0.1 at 2013-07-03 13:09:51 +0300 Processing by ReleasesController#index as HTML Read fragment views/all_available_releases/41cb0a928326986f35f41c52bb3d8352 (0.1ms) Rendered releases/index.html.erb within layouts/application (0.6ms) Completed 200 OK in 5ms (Views: 4.0ms | ActiveRecord: 0.0ms) ``` I even tried using `Rails.cache.delete("all_available_releases")` and it didn't work either. if I delete `<%cache "all_available_releases"%>` (and one `<%end%>`) from my html.erb the caching works fine and gets expired whenever it should.

Original source