缓存分页集合的Rails



只是研究缓存分页项目集合的最佳方式。目前正在使用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个项目。

有什么解决办法吗?

使用分页集合,您只需要得到一个数组。任何试图篡改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 %>

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

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

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

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

只有当您能够保证新记录总是出现在最后一页,并且不会删除任何记录时,使用最大updated_at才是一条可靠的方法。

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

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

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

和轨道4叉:https://github.com/joshblour/scope_cache_key

最新更新