[Feature Request] Error if `content_for` called from within fragment cache

Hi all,

This was originally incorrectly posted at https://github.com/rails/rails/issues/28072 - as advised, I’m now posting it here instead.

It is very easy to accidentally call content_for from within a block that will be fragment cached, especially if the cached fragment calls out to a partial. eg:

<%= cache “fragment” do %>

<%= render “javascript_widget” %>

<% end %>

<%= content_for :javascript_includes %>

<div class="jsPlaceholder /> <p><% content_for :javascript_includes do %></p> <p><%= javascript_include_tag … %></p> <script>doTheThing('.jsPlaceholder')</script> <p><% end %></p> <p><strong>Steps to reproduce</strong> Call content_for from within code that will end up in a fragment cache</p> <p><strong>Expected behavior</strong>An error should be raised letting the developer know that the content_for would not occur.</p> <p><strong>Actual behavior</strong> The contents of the content_for are silently discarded.</p>

Call content_for from within code that will end up in a fragment cache

An error should be raised letting the developer know that the content_for would not occur.

Sounds sensible to me.

The only danger that comes to mind is if someone is using content_for to pass information around between two chunks within a cached fragment — that would currently be working fine, and the error would break it.

Maybe we can raise specifically if you try to fetch content across a cache boundary. Or maybe we don’t need to care about that.

If someone would like to work up a PR to do one or both of the above, please do go ahead :+1:t2:

Matthew

I agree that an error would be much better than the current behavior where it appears to work the first time you load the page / every time you try it out in development (with caching off) but then silently and subtly fails to work after it ends up in production (for every non-first page load).

Even better would be to actually support doing this (proposed here (and before that, here, etc.)). :smiley: