ruby-on-railscachingpaginationrussian-doll-caching

Rails caching a paginated collection


Just doing some research on the best way to cache a paginated collection of items. Currently using jbuilder to output JSON and have been playing with various cache_key options.

The best example I've seen is by using the latest record's updated_at plus the amount of items in the collection.

def cache_key
      pluck("COUNT(*)", "MAX(updated_at)").flatten.map(&:to_i).join("-")
end

defined here: https://gist.github.com/aaronjensen/6062912

However this won't work for paginated items, where I always have 10 items in my collection.

Are there any workarounds for this?


Solution

  • With a paginated collection, you're just getting an array. Any attempt to monkey patch Array to include a cache key would be a bit convoluted. Your best bet it just to use the cache method to generate a key on a collection-to-collection basis.

    You can pass plenty of things to the cache method to generate a key. If you always have 10 items per page, I don't think the count is very valuable. However, the page number, and the last updated item would be.

    cache ["v1/items_list/page-#{params[:page]}", @items.maximum('updated_at')] do
    

    would generate a cache key like

    v1/items_list/page-3/20140124164356774568000
    

    With russian doll caching you should also cache each item in the list

    # index.html.erb
    <%= cache ["v1/items_list/page-#{params[:page]}", @items.maximum('updated_at')] do %>
      <!-- v1/items_list/page-3/20140124164356774568000 -->
      <%= render @items %>
    <% end %>
    
    # _item.html.erb
    <%= cache ['v1', item] do %>
      <!-- v1/items/15-20140124164356774568000 -->
      <!-- render item -->
    <% end %>