Collection caching: render to strings

Hi, I am a contributor to Thredded, a Rails forums engine, and we have an interesting problem.

We currently all cache the posts on a topic page using collection caching.

This requires the entire post to be cached due to the current collection caching interface,

even though only the post content itself is slow to render. That’s was not a large problem for us until now.

However, @EllaNancyFay is currently working on a feature for Thredded that requires something that cannot be cached

to be inserted at the end of the post partial, but that’s not possible via the current render collection: …, cache: … interface.

I’m wondering if a feature that lets us render a collection to Strings would belong in Rails core?

So a method such as render_to_string**s**(partial:, collection:, cache:),

returning an Array of [ [item, "rendered html"], ... ].

Here is an example implementation: https://github.com/thredded/thredded/pull/536/files#diff-00110786c7c8a611fd05432b7fb15270

Been a while since I’ve last worked with that code but doesn’t a collection cache render return a collection of rendered HTML strings?

I think you might be able to stitch the objects and their rendered HTML together like this:

@posts.zip(render(partial: ’posts/post’, collection: @posts, cached: true))

Though overall, I don’t think we’re going to change the interface here. Thanks! :slight_smile:

No, a collection cache render returns a single string.

Right, it’s joined with the spacer template. Maybe that’s usable?

https://github.com/rails/rails/blob/9c0a82d5766c2c01f1e75eb5c70c65f28ec6a665/actionview/lib/action_view/renderer/partial_renderer.rb#L326

If you mean whether cache_collection_render is usable, I think it would be but it is currently private!

The implementation I’ve linked to above does use PartialRenderer, and effectively reimplements cache_collection_render using only public APIs.