What is the convention for where the cache do
block goes?
Does it belong in "calling" template or the "inner" template that the "outer" template renders?
In some examples, I see the responsibility for caching a template B going in the "parent" or "calling" template, A—the template that renders template B. For example, https://blog.appsignal.com/2018/04/03/russian-doll-caching-in-rails.html says:
On the product index, we’ve wrapped each product partial in a cache block.
and shows this example:
# app/views/products/index.html.erb
<h1>Products</h1>
<% @products.each do |product| %>
<% cache product do %>
<%= render product %>
<% end %>
<% end %>
This identical example can also be found at https://edgeguides.rubyonrails.org/caching_with_rails.html#fragment-caching
But isn't that responsibility in the wrong place? That puts the burden on the user of the template rather than on the template itself (to cache itself). Which means that you have to remember, every time you render the product
template, to wrap it in a cache
block if you want it to be cached. This leads to duplicated code ("not DRY").
Wouldn't it be better, then, to put it in the template itself? Something like this, perhaps:
# app/views/products/_product.html.erb
<% cache product do %>
<article>
<h1><%= product.title %></h1>
…
</article>
<% end %>
There appears to be an examples of a template wrapping its own content in a cache
block like this later on in the guide, at https://edgeguides.rubyonrails.org/caching_with_rails.html#russian-doll-caching:
For example, take the following view:
<% cache product do %> <%= render product.games %> <% end %>
Which in turn renders this view:
<% cache game do %> <%= render game %> <% end %>
but it's not 100% clear in precisely which files those templates actually belong. What file names would those views conventionally live in?
I can easily imagine/assume that the 1º template would live in either app/views/products/show.html.erb
or app/views/products/_product.html.erb
depending on whether it's an action view or a partial (it doesn't really matter which it is for the purposes of this discussion):
# app/views/products/show.html.erb ? # app/views/products/_product.html.erb ? <% cache product do %> <%= render product.games %> <% end %>
Where I am actually confused is the 2º template:
# app/views/games/_game.html.erb ? <% cache game do %> <%= render game %> <% end %>
From context, I think we know this is a partial for a game (rendered once for each game in the collection passed in the _product
template), so I guess it would live at app/views/games/_game.html.erb
by convention.
But if that is the case, which is the 3º template that it is rendering here with render game
?? It looks like it is rendering a partial for game
— but aren't we already inside of the partial for game
? Wouldn't this result in infinite recursion (games/_game.html.erb
rendering itself recursively)?
Am I missing something obvious? Or is this just a poor example that needs to be updated in the guide? If so, what would an improved example look like?