Ruby on rails 请解释Rails缓存在这种情况下的行为

Ruby on rails 请解释Rails缓存在这种情况下的行为,ruby-on-rails,caching,Ruby On Rails,Caching,假设我有5个标签:tag1,tag2…tag5。如果我这样做: Rails.cache.fetch("all.tags") { Tag.all } 然后我写了Rails.cache.fetchall.tags,我看到了5个标签。如果我添加了另一个标记,并再次尝试从缓存中提取,那么新标记也会被加载。为什么呢 编辑:这是我的实际代码: Rails.cache.fetch("autocomplete.#{term}") { puts "Cache miss #{term}"; Tag.startin

假设我有5个标签:tag1,tag2…tag5。如果我这样做:

Rails.cache.fetch("all.tags") { Tag.all }
然后我写了Rails.cache.fetchall.tags,我看到了5个标签。如果我添加了另一个标记,并再次尝试从缓存中提取,那么新标记也会被加载。为什么呢

编辑:这是我的实际代码:

Rails.cache.fetch("autocomplete.#{term}") { puts "Cache miss #{term}"; Tag.starting_with(term) }
Where start_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">] 
这是不可能的

缓存在键/值对上工作

Rails.cache.fetch("all.tags") { Tag.all }
它将始终返回存储的key all.tags的值

您是否可以尝试读取存储在缓存中的值。然后添加新标签

Rails.cache.read("all.tags")
我知道这不是你的问题的答案,但我也想知道为什么会这样


您是否在使用缓存设置进行其他操作?

您尚未显示标记的代码。以\u术语开始\u,但我敢打赌它是一个作用域或返回类似的作用域,即类似于

Tag.where(...)
这与Tag.all有着本质的区别。我首先要问你的问题:Tag.all是一个数组,但上面的是一个范围。作用域是惰性计算的,只有在调用作用域上要求作用域为实际数组的方法时,才会从数据库请求行

这里发生的事情是缓存实际的作用域,而不是作用域将选择的行。另一种看待它的方式是,此时您正在缓存构成查询的条件,而不是查询结果

当您从缓存中读取时,您的作用域将从缓存中检索,尝试显示它的行为将迫使rails对其进行评估。此计算发生在从缓存检索范围之后,因此您总是可以获得新的结果

最简单的方法是强制评估范围,例如

Rails.cache.fetch('cache_key') { Tag.starting_with(term).all }

如何将数据存储在缓存中?它必须通过Rails.cache.write'all.tags',Tag.all完成。可能是您在将数据存储到缓存时拼错了密钥。我对问题进行了更新。据我所知,我并没有对缓存做任何花哨的事情。奇怪。。。我也试过同样的方法,但效果很好。您正在使用哪个版本的rails?3.2.2。。。这很奇怪。这可能是因为我正在进行开发吗?我不这么认为。据我所知,它在每种环境中都起着相同的作用。