想象一下,我有5个标签:tag1,tag2...tag5
。如果我执行以下操作:
Rails.cache.fetch("all.tags") { Tag.all }
然后我写Rails.cache.fetch("all.tags")
,我看到了5个标签。如果我添加另一个标记,并且我尝试再次从缓存中获取,则还会加载新标记。那是为什么?
编辑:这是我的实际代码:
Rails.cache.fetch("autocomplete.#{term}") { puts "Cache miss #{term}"; Tag.starting_with(term) }
starting_with
在哪里找到以某些字母开头的标签。这是我在控制台中获得的行为:
1.9.3p125 :046 > Rails.cache.read("autocomplete.ta")
Tag Load (1.0ms) SELECT "tags".* FROM "tags" WHERE (name like 'ta%')
=> [#<Tag id: 10, name: "tag1">, #<Tag id: 11, name: "tag2">, #<Tag id: 12, name: "tag3">, #<Tag id: 13, name: "tag4">]
1.9.3p125 :048 > Tag.create(name:"tag5")
(0.2ms) begin transaction
SQL (1.0ms) INSERT INTO "tags" ("name") VALUES (?) [["name", "tag5"]]
(150.9ms) commit transaction
=> #<Tag id: 14, name: "tag5">
1.9.3p125 :049 > Rails.cache.read("autocomplete.ta")
Tag Load (0.8ms) SELECT "tags".* FROM "tags" WHERE (name like 'ta%')
=> [#<Tag id: 10, name: "tag1">, #<Tag id: 11, name: "tag2">, #<Tag id: 12, name: "tag3">, #<Tag id: 13, name: "tag4">, #<Tag id: 14, name: "tag5">]
答案 0 :(得分:1)
不可能。
缓存处理键/值对。
Rails.cache.fetch("all.tags") { Tag.all }
它将始终返回存储键“all.tags”的值。
您是否可以尝试读取存储在缓存中的值。然后添加新标签
Rails.cache.read("all.tags")
根据你的问题,我知道它不是答案,但我也很想知道它为什么会发生。
你在使用缓存设置做其他事吗?
答案 1 :(得分:1)
你还没有展示Tag.starting_with_term
的代码,但我敢打赌它是一个范围或者返回范围之类的东西,比如
Tag.where(...)
这与Tag.all
我的初始问题根本不同:Tag.all
是一个数组,但上面是一个范围。范围是懒惰地评估的,只有在要求范围是实际数组的范围上调用方法时,才会从数据库中请求行。
这里发生的是您正在缓存实际范围,而不是范围将选择的行。另一种看待它的方法是说,目前你正在缓存构成查询的条件,而不是查询结果。
当您从缓存中读取时,您会从缓存中检索范围,并且尝试显示它的行为会强制rails对其进行评估。从缓存中检索作用域后,将进行此评估,以便始终获得新的结果。
最简单的方法是强制评估范围,例如
Rails.cache.fetch('cache_key') { Tag.starting_with(term).all }