ruby-on-rails - Rails 4 不同 View 的片段缓存

标签 ruby-on-rails caching memcached fragment-caching russian-doll-caching

在我的 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 %>
.....

我尝试使用的示例代码(不确定它是否好):

首先是索引页,没有俄罗斯娃娃。

enter image description here

第二个是带有评论的显示页面的俄罗斯娃娃。

enter image description here

最佳答案

缓存单个记录和缓存记录集合之间存在很大差异。

通过查看时间戳,您可以非常简单地判断单个记录是否已更改。默认的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/

相关文章:

ruby-on-rails - 如何将第一个用户添加到使用 Authlogic、Devise 等的 Rails 应用程序?

java - 将 Memcache 与 GAE、Java 和 JDO 事务结合使用

java - 使用存储在 memcache 中的 db 哈希表结合 cron 作业写入 google app engine Datastore

ruby-on-rails - 使用 declarative_authorization 保护敏感属性

mysql - 迭代内的数字总和 - Rails

wordpress - Bonno WordPress 主题缓存 CSS 无限更新

objective-c - ASIHTTPRequest 似乎总是缓存 JSON 数据

nosql - WSO2 DSS 是否支持 Memcache 和 Redis?

ruby-on-rails - Carrierwave 在生产端通过 "heroku rails console"从 s3 添加图片

asp.net-mvc - 使用 Scripts.Render 进行缓存清除,但没有 bundle URL