2

由于动作和页面缓存以及清扫器将从 Rails 4.0 中删除,我开始cache_digests在我的 Rails 3.2 应用程序中使用,因为我正遭受整个手动过期的噩梦。

但即使在阅读了一些教程(如何基于键的缓存过期工作缓存摘要#387 缓存摘要、...)之后,我也找不到一种好方法来处理没有可以提供时间戳的父对象的视图或类似的东西。

例如,如果DocumentTodolist使用关联touch上的选项,这可以完美地工作。Project

# app/views/projects/show.html.erb
<% cache @project do %>
  <%= render @project.documents %>
  <%= render @project.todolists %>
<% end %>

但是index行动呢?

# app/views/projects/index.html.erb
<% cache ??? do %>
  <% @projects.each do |project| %>
    ...
  <% end %>
<% end %>

当然,我可以使用任意密钥project_index,例如在项目模型发生任何更改时使其过期,但这需要清扫者或观察者并摆脱它们,包括显式过期是基于密钥过期的主要原因之一。

Rails 4.0的方法是什么?

4

3 回答 3

3
# app/views/projects/index.html.erb
<% cache @projects.scoped.maximum(:updated_at) do %>
  <% @projects.each do |project| %>
    ...
  <% end %>
<% end %>

更新项目时,会创建一个新的缓存页面....

于 2013-04-17T08:37:49.330 回答
2

只需这样做:

# app/views/projects/index.html.erb
<% cache @projects do %>
  <% @projects.each do |project| %>
    ...
  <% end %>
<% end %>

项目集合将创建缓存键,集合中在顺序或对象方面的任何更改都将创建不同的键。

如果您的视图显示与来自较低级别协会的项目相关的数据,它确实有一些限制,但是这是可以处理的。

于 2013-02-11T17:09:33.423 回答
2

我没有考虑太多,我自己也从未尝试过,但是您可以执行以下操作:

class TimestampAsCacheKey
  def initialize(prefix,timestamp)
    @key = prefix + timestamp.to_s
  end
  def cache_key # This is what Rails calls to get a key from object for caching
    @key
  end
end

...
# in your model:
ts = ... # somehow get the most recent timestamp of your projects, like
         # 1) either @projects.to_a.map(&:updated_at).max 
         #    or from `projects` table, like 
         #      Project.order("updated_at DESC").first.updated_at
         #      (you should further optimize the query, of course, but you get the idea)
         #    but probably not, since the whole point is to avoid hitting db
         # 2) or, better yet, from storing it in a global var, special DB table, etc
         #    (just update it there each time you save a project, 
         #    e.g. through after_save / after_commit)
@projects_last_updated_time = TimestampAsCacheKey.new("projects-timestamped-list-",ts)

然后在你看来:

<% cache @projects_last_updated_time do %>
  <% @projects.each do |project| %>
    ...
  <% end %>
<% end %>
于 2013-03-06T21:20:43.563 回答