9

只是对缓存分页项目集合的最佳方法进行一些研究。目前使用 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 个项目。

有什么解决方法吗?

4

2 回答 2

10

使用分页集合,您只会得到一个数组。任何试图修改 Array 以包含缓存键的尝试都会有点令人费解。您最好的选择是使用缓存方法在集合到集合的基础上生成一个密钥。

您可以将大量内容传递给缓存方法以生成密钥。如果您总是每页有 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 %>
于 2014-02-21T14:28:46.863 回答
3

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

正如您所说,除非您允许动态per_page值,否则集合计数是一种给定的无用。

最新updated_at的完全取决于您的收藏品的分类。

想象一下,添加了一条新记录并在第一页结束。这意味着一条记录,以前的第 1 页,现在进入第 2 页。以前的第 2 页记录现在变成第 3 页。如果新的第 2 页记录的更新时间不超过前一个最大值,则缓存键保持不变,但集合不是!删除记录时也会发生同样的情况。

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

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

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

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

和 rails 4 fork: https ://github.com/joshbour/scope_cache_key

于 2015-06-29T14:52:58.353 回答