Rendering collections in Rails, with custom cache parameters
April 19, 2021Rails has a simple syntax for rendering a collection of partials and caching them all in one go. Under the hood it'll try and fetch all the cached views at once, minimising unnecessary I/O.
<%= render collection: @posts, partial: "posts/post", cached: true %>
This works well, but what happens if the partial cache depends on additional data? For example - if something was specific to the logged in user. Generally you'd instead handle this with the cache
helper in the partial instead.
<%= cache [post, current_user] do %>
Unfortunately this means you'll need to hit your cache store for each individual partial which is not as performant.
I've long looked for a way to solve this but couldn't find the solution. It didn't appear to be documented anywhere, until I stumbled across it in the cache
helper's source code.
You can actually pass a proc to the cached
argument and control the cache constraints from the top render` call!
<%= render collection: @posts, partial: "posts/post", cached: -> (post) { [post, current_user] } %>
Just like that you get the performance benefits of a single cache hit and don't need to dirty your partials with manual cache
calls.
A blog about Laravel & Rails by Dwight Watson;
developer of Roomies.com, myRent.co.nz, High School Notes & StudentVIP.com.au.
