ruby-on-railscachingfragment-caching

rails4 caching naming conventions


I have a rails 4 app. I have to differentiate the different cache keys somehow but don't know the naming conventions.

FIRST EXAMPLE:

I have a task model with index, completed_tasks and incoming_tasks actions. A have the same instance name (@tasks) though because of the pagination.

At the moment the cache-keys are named like below. My questions: 1. Is the cache-key structure good enough? 2. Is it important in which order I put the parts of the key in the array? For example [@tasks.map(&:id), @tasks.map(&:updated_at).max, 'completed-tasks'] is better than ['completed-tasks', @tasks.map(&:id), @tasks.map(&:updated_at).max]?

completed_tasks.html.erb

<% cache([@tasks.map(&:id), @tasks.map(&:updated_at).max, 'completed-tasks']) do %>
  <%= render @tasks %>
<% end %>

tasks.html.erb

<% cache([@tasks.map(&:id), @tasks.map(&:updated_at).max]) do %>
  <%= render @tasks %>
<% end %>

incoming_tasks.html.erb

<% cache([@tasks.map(&:id), @tasks.map(&:updated_at).max, 'incoming-tasks']) do %>
  <%= render @tasks %>
<% end %>

SECOND EXAMPLE:

I also have problem with the naming conventions of the russian-doll-caching:

products/index.html.erb

<% cache([@products.map(&:id), @products.map(&:updated_at).max]) do %>
  <%= render @products %>
<% end %>

_product.html.erb 

<% cache(product) do %>
  <%= product.name %>
  ....
<% end %>

Is this version good enough or I always should put some string in both the outer and inner caching key array to avoid problems with similarly named cache-keys on other pages. For instance I plan to put <% cache(@product) do %> on the profile#show page which would be exactly the same like the inner caching in my example. If the key has to be different what the rails convention is to name the inner an outer cache keys?


Solution

  • First, according to Russian Doll Caching article, I think it's not necessary to set the cache_key on your own, you could just leave it to rails, it generates cache_key auto. For example, the cache_key of @tasks = Task.incoming should differ from @tasks = Task.completed with something like views/task/1-20160330214154/task/2-20160330214154/d5f56b3fdb0dbaf184cc7ff72208195e and views/task/3-20160330214154/task/4-20160330214154/84cc7ff72208195ed5f56b3fdb0dbaf1

    cache [@tasks, 'incoming_tasks'] do
      ...
    end
    

    Second, As for the namespace, though the template digest will be the same but the @tasks digest will be different. So it seems to be okay without namespace in this case.

    cache @tasks do
      ...
    end
    

    Third, when it comes to namespace, I prefer prefix rather than suffix. i.e.

    cache ['incoming_tasks', @tasks] do
      ...
    end
    

    As the second example, I think this would do just fine.

    <% cache @product do # first layer cache %>
      <% cache @products do # second layer cache %>
        <%= render @products %>
      <% end %>
    
      <% cache @product do # second layer cache %>
        <%= product.name %>
        ....
      <% end %>
    <% end %>
    

    The caching key for app/views/products/show.html.erb will be something like views/product/123-20160310191209/707c67b2d9fb66ab41d93cb120b61f46. That last bit is a MD5 of the template file itself and all of its dependencies. It'll change if you change either the template or any of the dependencies, and thus allow the cache to expire automatically.

    For further reading: https://github.com/rails/cache_digests