ruby-on-railsrubyruby-on-rails-7

Clearing Fragment Caching from Console


I am new to Rails, going through the caching mechanism and facing a few issues in Fragment caching and not being able to get the solution

In development.rb

config.action_controller.perform_caching = true
config.cache_store = :memory_store

In posts/index.html.rb

<p style="color: green"><%= notice %></p>

<h1>Posts</h1>

<div id="posts">
  <% @posts.each do |post| %>
  <% cache post do %>
    <%= logger.info "Rendering post #{post.id}" %>
    <%= render post %>
  <% end %>
    <p>
      <%= link_to "Show this post", post %>
    </p>
  <% end %>
</div>

<%= link_to "New post", new_post_path %>

The caching is working as expected and on update, the caching is expiring. According to the doc trying to delete the cache from the console

rails c

post = Post.first
Rails.cache.delete("views/#{post.cache_key}")

Returning false

On debugging, I found

cache_key = post.cache_key_with_version
Rails.cache.delete("views/#{cache_key}")

This also did not work Rails.cache.clear is also not working. It would be great help to understand this.


Solution

  • From the official guide

    When your application receives its first request to this page, Rails will write a new cache entry with a unique key. A key looks something like this:

    views/products/index:bea67108094918eeba42cd4a6e786901/products/1
    

    The string of characters in the middle is a template tree digest. It is a hash digest computed based on the contents of the view fragment you are caching. If you change the view fragment (e.g., the HTML changes), the digest will change, expiring the existing file.

    Also pay attention here to the view name (views/products/index). You didn't use it when tried to clear cache

    If you want to delete such cache, you can invoke delete_matched method

    Rails.cache.delete_matched("views/posts/index*/posts/#{post.id}*")
    

    You can manually check stored keys using

    Rails.cache.instance_variable_get(:@data).keys
    

    Also pay attention to cache store. If you use memory store, it is process-dependent. So cache in the rails s and rails c are different. To check server cache use some debugger like this in your view

    <% binding.irb %>
    

    or same in the controller