Search code examples
ruby-on-railsfragment-cachingruby-on-rails-4

How to handle key based expiration of collections if there is no parent model in Rails 4.0?


Since action and page caches and sweepers will be removed from Rails 4.0, I started to use cache_digests in my Rails 3.2 application, since I'm suffering from this whole manual expiration nightmare.

But even after reading some tutorials (How key-based cache expiration works, Cache Digests, #387 Cache Digests, ...) I couldn't find a good way to handle views where there is no parent object which could provide a time stamp or something similar.

For example this works flawlessly, if Document and Todolist use the touch option on the Project association.

# app/views/projects/show.html.erb
<% cache @project do %>
  <%= render @project.documents %>
  <%= render @project.todolists %>
<% end %>

But what about the index action?

# app/views/projects/index.html.erb
<% cache ??? do %>
  <% @projects.each do |project| %>
    ...
  <% end %>
<% end %>

Of course I could just use any arbitrary key like project_index and expire it on any change of a project model, but that would require a sweeper or an observer and getting rid of them including the explicit expiration is one of the major reasons for key based expiration.

What is the Rails 4.0 way to do this?


Solution

  • Just do this:

    # app/views/projects/index.html.erb
    <% cache @projects do %>
      <% @projects.each do |project| %>
        ...
      <% end %>
    <% end %>
    

    The projects collection will create the cache key, any changes in the collection in terms of order or objects will create a different key.

    It does have some limitations if your views are showing data relating to projects from lower level associations, however this can be dealt with.