rails 4个不同视图的片段缓存
rails 4 fragment caching for different views
在我的 rails 4 应用程序中,我试图通过缓存起飞,但由于不同版本的缓存键设置、缓存助手和自动过期,我有点困惑。
所以让我通过几个例子来问这个问题。我不会故意把例子移到不同的问题上,因为我觉得这样任何人都可以一眼就理解其中的细微差别。
1: 侧边栏中的最新用户
我想显示最新的用户。这当然对应用程序中的所有用户都是一样的,并显示在所有页面上。在 railscasts 中,我看到了一个类似的例子,它通过在控制器中调用 expire_fragment...
而过期。但根据其他资源,这应该会在某些情况发生变化时自动过期(例如新用户注册)。所以我的问题是:我是否正确设置了密钥,它会自动过期吗?
_sidebar.html.erb(显示在侧边栏的所有页面上)
<% cache 'latest-users' %>
<%= render 'users/user_sidebar' %>
<% end %>
_用户_sidebar.html.erb
<% @profiles_sidebar.each do |profile| %>
<%= profile.full_name %>
........
<% end %>
2:产品展示页面
我想展示给定的产品(仅在展示页面上)。这对所有用户来说都是一样的,但是因为有更多的产品,所以有更多的版本。问题又是一样的:我设置的密钥是否正确,它会自动过期吗?
products/show.html.erb
<% cache @product %>
<%= @product.name.upcase %>
<%= @product.user.full_name %>
<% end %>
3:products/index(使用 will-paginate gem 分页)
在这里,我想一次缓存分页给定页面上的所有产品,因此产品会以块的形式缓存。这对所有用户也是一样的,并且只在 products index page
上显示。 (稍后我想为该页面上的个别产品实施 russian-doll-caching
。)我的问题:我这样做是否正确,它会自动过期吗?
产品索引。html.erb
<% cache [@products, params[:page]] %>
<%= render @products %>
<% end %>
_product.html.erb
<%= product.name %>
<%= product.user.full_name %>
.....
我尝试使用的示例代码(不确定它是否合适):
首先是索引页,没有俄罗斯套娃。
第二个是带有评论的展示页面的俄罗斯娃娃。
恕我直言,缓存键是整个概念的精神。
现在让我们讨论这些例子。
- 边栏中的最新用户:固定字符串作为缓存键
cache_key
可能是 views/latest-users/7a1156131a6928cb0026877f8b749ac9
其中摘要 7a11561..
是缓存块文字的 MD5。
在这种情况下,缓存仅在您更改模板或此块中的任何内容时过期。
<% cache 'latest-users' do %>
<%= render 'users/user_sidebar' %>
<% end %>
- 产品展示页面:对象作为缓存键
cache_key
可能是 views/product/123-20160330214154/9be3eace37fa886b0816f107b581ed67
,请注意缓存是带有 #{product.to_s}
/#{product.id}
-#{product.updated_at}
.
的命名空间
在这种情况下,缓存在 (1) product.updated_at
更改或 (2) 缓存块文字更改时过期。
注意缓存与不同产品的区别 id
。
<% cache @product %>
<%= @product.name.upcase %>
<%= @product.user.full_name %>
<% end %>
- products/index(使用 will-paginate gem 分页):数组作为缓存键
cache_key
可能 views/product/123-20160330214154/product/456-20160330214154/d5f56b3fdb0dbaf184cc7ff72208195e
对此不确定。但无论如何,它应该像这样展开。
在这种情况下,缓存在 (1) product-123 或 product-456 更改(product.updated_at
更改)或 (2) 缓存块文字更改时过期。
并且缓存与@products
的不同内容有ids
的区别,所以不需要附加params[:page]
,它会缓存每个不同的页面,因为它们的@products
内容.
<% cache [@products, params[:page]] %>
<%= render @products %>
<% end %>
您可以阅读 article written by DHH, it described Russian Doll Caching very well. And the API doc
缓存单个记录和缓存记录集合之间存在很大差异。
您可以通过查看时间戳非常简单地判断单个记录是否已更改。默认的 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
作为俄罗斯套娃 "outer layer" 中的缓存键。
在这种情况下,完全加载记录是有意义的。你可以忽略我之前关于 .ids
.
的评论
products/index.html.erb:
<% cache([@products.map(&:id), @products.map(&:updated_at).max]) do %>
<%= render @products %>
<% end %>
products/_product.html.erb:
<% cache(product) do %>
<%= product.name %>
<% end %>
在我的 rails 4 应用程序中,我试图通过缓存起飞,但由于不同版本的缓存键设置、缓存助手和自动过期,我有点困惑。
所以让我通过几个例子来问这个问题。我不会故意把例子移到不同的问题上,因为我觉得这样任何人都可以一眼就理解其中的细微差别。
1: 侧边栏中的最新用户
我想显示最新的用户。这当然对应用程序中的所有用户都是一样的,并显示在所有页面上。在 railscasts 中,我看到了一个类似的例子,它通过在控制器中调用 expire_fragment...
而过期。但根据其他资源,这应该会在某些情况发生变化时自动过期(例如新用户注册)。所以我的问题是:我是否正确设置了密钥,它会自动过期吗?
_sidebar.html.erb(显示在侧边栏的所有页面上)
<% cache 'latest-users' %>
<%= render 'users/user_sidebar' %>
<% end %>
_用户_sidebar.html.erb
<% @profiles_sidebar.each do |profile| %>
<%= profile.full_name %>
........
<% end %>
2:产品展示页面
我想展示给定的产品(仅在展示页面上)。这对所有用户来说都是一样的,但是因为有更多的产品,所以有更多的版本。问题又是一样的:我设置的密钥是否正确,它会自动过期吗?
products/show.html.erb
<% cache @product %>
<%= @product.name.upcase %>
<%= @product.user.full_name %>
<% end %>
3:products/index(使用 will-paginate gem 分页)
在这里,我想一次缓存分页给定页面上的所有产品,因此产品会以块的形式缓存。这对所有用户也是一样的,并且只在 products index page
上显示。 (稍后我想为该页面上的个别产品实施 russian-doll-caching
。)我的问题:我这样做是否正确,它会自动过期吗?
产品索引。html.erb
<% cache [@products, params[:page]] %>
<%= render @products %>
<% end %>
_product.html.erb
<%= product.name %>
<%= product.user.full_name %>
.....
我尝试使用的示例代码(不确定它是否合适):
首先是索引页,没有俄罗斯套娃。
第二个是带有评论的展示页面的俄罗斯娃娃。
恕我直言,缓存键是整个概念的精神。
现在让我们讨论这些例子。
- 边栏中的最新用户:固定字符串作为缓存键
cache_key
可能是 views/latest-users/7a1156131a6928cb0026877f8b749ac9
其中摘要 7a11561..
是缓存块文字的 MD5。
在这种情况下,缓存仅在您更改模板或此块中的任何内容时过期。
<% cache 'latest-users' do %>
<%= render 'users/user_sidebar' %>
<% end %>
- 产品展示页面:对象作为缓存键
cache_key
可能是 views/product/123-20160330214154/9be3eace37fa886b0816f107b581ed67
,请注意缓存是带有 #{product.to_s}
/#{product.id}
-#{product.updated_at}
.
在这种情况下,缓存在 (1) product.updated_at
更改或 (2) 缓存块文字更改时过期。
注意缓存与不同产品的区别 id
。
<% cache @product %>
<%= @product.name.upcase %>
<%= @product.user.full_name %>
<% end %>
- products/index(使用 will-paginate gem 分页):数组作为缓存键
cache_key
可能 views/product/123-20160330214154/product/456-20160330214154/d5f56b3fdb0dbaf184cc7ff72208195e
对此不确定。但无论如何,它应该像这样展开。
在这种情况下,缓存在 (1) product-123 或 product-456 更改(product.updated_at
更改)或 (2) 缓存块文字更改时过期。
并且缓存与@products
的不同内容有ids
的区别,所以不需要附加params[:page]
,它会缓存每个不同的页面,因为它们的@products
内容.
<% cache [@products, params[:page]] %>
<%= render @products %>
<% end %>
您可以阅读 article written by DHH, it described Russian Doll Caching very well. And the API doc
缓存单个记录和缓存记录集合之间存在很大差异。
您可以通过查看时间戳非常简单地判断单个记录是否已更改。默认的 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
:
@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
作为俄罗斯套娃 "outer layer" 中的缓存键。
在这种情况下,完全加载记录是有意义的。你可以忽略我之前关于 .ids
.
products/index.html.erb:
<% cache([@products.map(&:id), @products.map(&:updated_at).max]) do %>
<%= render @products %>
<% end %>
products/_product.html.erb:
<% cache(product) do %>
<%= product.name %>
<% end %>