没有扫描程序在Rails中清除缓存的正确方法是什么

时间:2012-12-11 15:09:13

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

从Rails 4中删除观察者和扫描者。酷。 但是缓存和清除缓存的方法是什么呢?

我读到了关于俄罗斯娃娃的缓存。它很好,除了它只涉及视图渲染缓存。它不会阻止数据库被击中。

例如:

<% cache @product do %>
  Some HTML code here
<% end %>

您仍然需要从数据库中获取@product才能获得cache_key。因此,页面或动作缓存仍可用于防止不必要的负载。

我有时会使用一些超时来清除缓存,但是如果记录没有改变会怎样?

至少对于扫地机你可以控制这方面。什么是正确方式进行缓存并清除它?

谢谢! :)

1 个答案:

答案 0 :(得分:8)

欢迎来到计算机科学中的两个难题之一,缓存失效:)

您必须手动处理它,因为缓存对象的逻辑与缓存视图不同,缓存视图可以简单地从它显示的对象派生,应该是无效的应用程序和情境依赖。

您转到此方法是Rails.cache.fetch方法。 Rails.cache.fetch有3个参数;缓存键,选项哈希和块。它首先尝试根据密钥读取有效的缓存记录;如果该密钥存在且尚未过期,则它将从缓存中返回该值。如果它找不到有效的记录,它将从块中获取返回值,并使用指定的密钥将其存储在缓存中。

例如:

@models = Rails.cache.fetch my_cache_key do
  Model.where(condition: true).all
end

这将缓存块并重用结果,直到某些内容(tm)使密钥无效,从而强制重新评估该块。另请注意方法链末尾的.all。通常,Rails会返回一个将被缓存的ActiveRecord关系对象,然后当你第一次尝试使用@models时,会对其进行评估,整齐地回避缓存。 .all调用强制Rails急切加载记录并确保它是我们缓存的结果,而不是问题。

现在你已经获得了所有缓存并且再也没有与数据库通信,我们必须确保覆盖另一端,使缓存无效。这是通过Rails.cache.delete方法完成的,该方法只需要一个缓存键并将其删除,从而在下次尝试获取时导致错过。您还可以使用f force: true选项强制重新评估块。哪个适合你。

这一切的科学就是在哪里调用Rails.cache.delete,在天真的情况下,这将是针对单个实例的更新和删除,以及更新,删除,创建集合的任何成员。总会有蜂角落的情况,它们总是特定于应用,所以我无法帮助你。

我在这个答案中假设您将设置一些理智的缓存存储,如memcached或Redis。

还记得将它添加到config / environments / development.rb:

config.cache_store = :null_store

或者你的开发环境会缓存,你最终会因为沮丧而无毛。

如需进一步参考,请阅读:Everyone should be using low level caching in RailsThe rails API docs

值得注意的是,功能不会从Rails 4中删除,只是提取到gem中。如果您需要或希望扫描仪的完整功能,只需将其添加回您的应用程序,并在Gemfile中使用gem 'rails-observers'行。那个宝石包含从Rails 4核心移除的清扫工和观察者。

我希望你能帮助你开始。