在我的 Rails 4 应用程序中,我尝试启动缓存,但由于缓存键设置、缓存助手和自动过期的不同版本,我有点困惑。
所以让我通过几个例子来问这个问题。我不会故意将示例转移到不同的问题,因为我觉得这样任何人都可以一眼理解其中的细微差别。
1:侧边栏最新用户
我想显示最新的用户。当然,这对于应用程序中的所有用户都是相同的,并显示在所有页面上。在railscasts中,我看到了一个类似的例子,它通过在 Controller 中调用expire_fragment...
而过期。但根据其他资源,当发生变化时(例如新用户注册),这应该自动过期。所以我的问题是:我是否正确设置 key 并且它会自动过期吗?
_sidebar.html.erb(显示在侧边栏的所有页面上)
<% cache 'latest-users' %>
<%= render 'users/user_sidebar' %>
<% end %>
_users_sidebar.html.erb
<% @profiles_sidebar.each do |profile| %>
<%= profile.full_name %>
........
<% end %>
2:产品展示页面
我想显示给定的产品(仅在显示页面上)。对于所有用户来说这也是一样的,但是由于产品更多,所以版本也更多。问题又是一样的:我是否正确设置 key 并且它会自动过期吗?
产品/show.html.erb
<% cache @product %>
<%= @product.name.upcase %>
<%= @product.user.full_name %>
<% end %>
3:产品/索引(使用 will-paginate gem 分页)
在这里,我想立即缓存分页的给定页面上的所有产品,以便产品以 block 的形式缓存。这对于所有用户来说也是相同的,并且仅显示在产品索引页面
上。 (稍后我想为此页面上的各个产品实现 Russian-doll-caching
。)我的问题:我这样做对吗?它会自动过期吗?
产品索引.html.erb
<% cache [@products, params[:page]] %>
<%= render @products %>
<% end %>
_product.html.erb
<%= product.name %>
<%= product.user.full_name %>
.....
我尝试使用的示例代码(不确定它是否好):
首先是索引页,没有俄罗斯娃娃。
第二个是带有评论的显示页面的俄罗斯娃娃。
最佳答案
缓存单个记录和缓存记录集合之间存在很大差异。
通过查看时间戳,您可以非常简单地判断单个记录是否已更改。默认的cache_key方法的工作原理如下:
Product.new.cache_key # => "products/new" - never expires
Product.find(5).cache_key # => "products/5" (updated_at not available)
Person.find(5).cache_key # => "people/5-20071224150000" (updated_at available)
然而,判断集合何时过时很大程度上取决于它的使用方式。
在您的第一个示例中,您只真正关心 created_at
时间戳 - 在其他情况下,您可能想查看记录何时更新,甚至何时插入/更新关联记录。这里没有正确答案。
1.
首先,您将拉取按 created_at
排序的 N 个用户:
@noobs = User.order(created_at: :desc).limit(10)
我们可以通过查看集合中的第一个用户来简单地使缓存失效。
<!-- _sidebar.html.erb -->
<% cache(@noobs.first) do %>
<%= render partial: 'users/profile', collection: @noobs %>
<% end %>
我们可以这样做,因为我们知道如果有新用户注册,他会将之前的第一名位置拉低。
然后我们可以使用俄罗斯娃娃缓存来缓存每个单独的用户。请注意,由于该部分称为 profile
,因此该部分会传递局部变量 profile
:
<!-- users/_profile.html.erb -->
<% cache(profile) do %>
<%= profile.full_name %>
<% end %>
2.
是的。它会过期。 您可能想要像其他示例一样使用俄罗斯娃娃缓存。
3.
对于分页集合,您可以使用数组中记录的 ID 来创建缓存键。
已编辑。
由于您不想提供可能更新的产品的陈旧表示,因此您还希望使用 updated_at
作为俄罗斯娃娃“外层”中的缓存键。
在这种情况下,完全加载记录是有意义的。您可以忽略我之前关于 .ids
的评论。
产品/index.html.erb:
<% cache([@products.map(&:id), @products.map(&:updated_at).max]) do %>
<%= render @products %>
<% end %>
产品/_product.html.erb:
<% cache(product) do %>
<%= product.name %>
<% end %>
关于ruby-on-rails - Rails 4 不同 View 的片段缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36309075/