使用/ Rails在Agile Web开发中缓存Rails 4

时间:2014-04-21 18:24:40

标签: ruby-on-rails ruby caching ruby-on-rails-4

我正在通过使用Rails4的敏捷Web开发工作,我刚刚阅读了(第一部分)有关缓存视图部分的内容,以避免压倒数据库。 我当然在开发环境的配置中将缓存选项设置为true。

问题在于缓存似乎无法正常工作。 这是我的app / views / store / index.html.erb文件,与本书中给出的文件完全相同,以启用缓存:

<% if notice %>
  <p id="notice"><%= notice %></p>
<% end %>

<h1>Your Pragmatic Catalog</h1>

<% cache ['store', Product.latest] do %>
  <% @products.each do |product| %>
    <% cache ['entry', product] do %>
      <div class="entry">
        <%= image_tag(product.image_url) %>
        <h3><%= product.title %></h3>
        <%= sanitize(product.description) %>
        <div class="price_line">
          <span class="price"><%= number_to_currency(product.price) %></span>
        </div>
      </div>
    <% end %>
  <% end %>
<% end %>

这是rails服务器日志,清楚地显示数据库被多次访问(尽管一行提到了缓存):http://pastebin.com/v2jGiHKL

这是我的app / views / store / index.html.erb文件,其中我尝试了其他用于缓存的内容:

<% if notice %>
  <p id="notice"><%= notice %></p>
<% end %>

<h1>Your Pragmatic Catalog</h1>

<% cache('caching') do %>
  <% @products.each do |product| %>
      <div class="entry">
        <%= image_tag(product.image_url) %>
        <h3><%= product.title %></h3>
        <%= sanitize(product.description) %>
        <div class="price_line">
          <span class="price"><%= number_to_currency(product.price) %></span>
        </div>
      </div>
  <% end %>
<% end %>

以下是相应的日志,显示缓存成功(因为未查询数据库):http://pastebin.com/ZTk9A9RA

有人可以解释为什么一个似乎工作而不是另一个,或者第一个应该如何工作?谢谢:))

请注意,在本书中,它表示启用了缓存后,如果更改是在缓存块内进行的,则重新加载商店页面不应显示store / index.html.erb的新部分;但两种情况都有。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

传递给cache api的参数是缓存密钥。该密钥的散列函数是存储缓存片段的位置,以及它将在何处查找。

在您的代码(cache('caching'))中,缓存密钥是硬编码的,并且永远不会更改,因此,除非缓存无效(在代码中手动执行,或者其TTL已通过) - 相同的片段将被发送给客户。

在本书的代码(cache ['store', Product.latest])中,密钥取决于最新产品。这意味着如果最新产品发生更改(另一个产品已添加或更新),则下一个调用将自动“知道”不从缓存中获取页面,而是重新创建缓存。

日志中显示的内容:

[1m[35mProduct Load (0.3ms)[0m  SELECT  "products".* FROM "products"   ORDER BY "products"."updated_at" DESC LIMIT 1

实际上是Product.latest的{​​{1}},不是的结果。

总结一下 - 两个代码片段都被缓存,但在示例代码中, 一个(小)命中数据库以验证缓存的有效性,无论页面是缓存的还是不

如果您自己使缓存失效,您可以保留代码的硬编码版本,但如果没有,您最好考虑失效方案,无论是示例代码建议还是别的。