欢迎来到计算机科学中的两个难题之一,缓存失效 :)
您必须手动处理该问题,因为缓存对象的逻辑与缓存视图不同,缓存视图可以简单地从它显示的对象派生,应该失效是应用程序和情况相关的。
你去这个方法就是Rails.cache.fetch
方法。Rails.cache.fetch
接受 3 个参数;缓存键、选项哈希和块。它首先尝试根据 key 读取有效的缓存记录;如果该键存在并且尚未过期,它将从缓存中返回该值。如果它找不到有效的记录,它会从块中获取返回值,并使用您指定的键将其存储在缓存中。
例如:
@models = Rails.cache.fetch my_cache_key do
Model.where(condition: true).all
end
这将缓存块并重用结果,直到某些东西 (tm) 使密钥无效,从而强制重新评估块。还要注意.all
方法链末尾的 。通常,Rails 会返回一个 ActiveRecord 关系对象,该对象将被缓存,然后在您@models
第一次尝试使用时对其进行评估,巧妙地避开缓存。该.all
调用强制 Rails 急切加载记录并确保它是我们缓存的结果,而不是问题。
因此,现在您已打开所有缓存并且不再与数据库通信,我们必须确保覆盖另一端,使缓存无效。这是通过Rails.cache.delete
简单地获取缓存键并将其删除的方法完成的,这会在您下次尝试获取它时导致丢失。您还可以使用force: true
fetch 选项来强制重新评估块。哪个适合你。
这一切的科学是在哪里调用Rails.cache.delete
,在幼稚的情况下,这将是对单个实例的更新和删除以及对集合的任何成员的更新、删除、创建。总会有一些角落案例,它们总是特定于应用程序,所以我在那里帮不了你太多。
我假设在这个答案中您将设置一些健全的缓存存储,例如 memcached 或 Redis。
还要记住将其添加到 config/environments/development.rb:
config.cache_store = :null_store
或者你的开发环境会缓存,你最终会因为沮丧而变得无毛。
如需进一步参考,请阅读:Everyone should be using low level caching in Rails and The rails API docs
还值得注意的是,Rails 4 中并没有删除功能,只是将其提取到 gem 中。如果您需要或想要扫地机的全部功能,只需将其添加回您的应用程序,并gem 'rails-observers'
在您的 Gemfile 中添加一行。该 gem 包含从 Rails 4 核心中删除的清扫器和观察器。
我希望这可以帮助您入门。