Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
638 views
in Technique[技术] by (71.8m points)

ruby - Rails 4.0 expire_fragment/cache expiration not working

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...