Rails缓存分页集合

时间:2014-02-13 23:35:32

标签: ruby-on-rails caching pagination russian-doll-caching

只是对缓存分页项目集合的最佳方法进行一些研究。目前使用jbuilder输出JSON并且一直在使用各种cache_key选项。

我见过的最好的例子是使用最新记录的updated_at加上集合中的项目数量。

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

此处定义:https://gist.github.com/aaronjensen/6062912

但是这对于分页项目不起作用,我的集合中总是有10个项目。

这有什么变通方法吗?

2 个答案:

答案 0 :(得分:10)

使用分页集合,您只需要一个数组。任何试图将补丁数组添加到包含缓存密钥的尝试都会有点复杂。最好的办法就是使用缓存方法在收集到收集的基础上生成密钥。

您可以将大量内容传递给缓存方法以生成密钥。如果你每页总共有10个项目,我认为计数不是很有价值。但是,页码和最后更新的项目将是。

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

会生成一个缓存键,如

v1/items_list/page-3/20140124164356774568000

使用俄语玩偶缓存,您还应该缓存列表中的每个项目

# 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 %>

答案 1 :(得分:2)

缓存分页集很棘手。使用集合计数和max updated_at的常用技巧大多不适用!

正如你所说,除非你允许动态per_page值,否则收集计数是无用的。

最新的updated_at完全取决于您的收藏品的排序。

想象一下,添加新记录并在第一页结束。这意味着先前第1页的一条记录现在进入第2页。之前的第2页记录现在变为第3页。如果新页面2记录的更新时间不比之前的最大值更高,则缓存键保持不变但是收集不是!删除记录时会发生同样的情况。

只有当您可以保证新记录总是在最后一页上结束并且不会删除任何记录时,使用max updated_at是一个可靠的方法。

作为解决方案,除了页码和updated_at值之外,您还可以在缓存键中包括总记录数和总最大per page。这将需要额外的查询,但值得,这取决于您的数据库配置和记录数。

另一个解决方案是使用一个考虑了实际收集内容的某种简化形式的密钥。例如,还要考虑所有记录ID。

如果您使用postgres作为数据库,这个gem可能对您有帮助,尽管我自己从未使用过它。 https://github.com/cmer/scope_cache_key

导轨4叉: https://github.com/joshblour/scope_cache_key