我正在尝试在内存缓存中保存已批准页面的大量 id 和永久链接,这样我就不必多次访问数据库来获取相同的数据。
我的代码:
if Rails.cache.exist?("ids_and_permalinks_array")
data = Rails.cache.fetch("ids_and_permalinks_array")
else
data = []
Page.approved.select('id, permalink').find_each { |f| data << f }
Rails.cache.write("ids_and_permalinks_array", data, :expires_in => 12.hours)
end
approved
上Page
很简单where(:approved => true)
,数据是一个大型对象子集数组,例如 #<Page id: 1, permalink: "page-permalink-1">
(该数组大约有 50,000 个对象)。
Rails.cache.write
行返回false
从控制台运行时,development.log 显示:Cache write: ids_and_permalinks_array ({:expires_in=>43200 seconds})
因此,日志显示它正在写入缓存,但是 Rails.cache.fetch("ids_and_permalinks_array")
返回nil
.
建议?我做错了什么明显的事情吗?
编辑
我也尝试过这个,但仍然没有将值写入缓存:
Rails.cache.fetch("ids_and_permalinks_array", :expires_in => 12.hours, :race_condition_ttl => 10.minutes) do
Page.approved.select('id, permalink').find_each { |p| data << p }
end
** 更新 2 **
我添加了Rails.logger.info("\n#{Rails.cache.exist?("ids_and_permalinks_array")\n")
到此代码所在方法调用的开头和结尾。每次在方法调用开始时,它都会记录 false
最后它记录 true
...所以,它正在工作,但它只是针对该方法调用的线程/实例进行设置吗?
最佳答案
当您使用Rails.cache.fetch
时,给定的 block 需要返回预期值。在:
Rails.cache.fetch("ids_and_permalinks_array", :expires_in => 12.hours, :race_condition_ttl => 10.minutes) do
Page.approved.select('id, permalink').find_each { |p| data << p }
end
该 block 的结果是nil
,因为这是find_each
的返回值。
尝试这样的事情:
Rails.cache.fetch("ids_and_permalinks_array", :expires_in => 12.hours, :race_condition_ttl => 10.minutes) do
[].tap do |data|
Page.approved.select('id, permalink').find_each { |p| data << p }
end
end
使用 tap 将确保将结果数组作为返回值传递给获取 block 。
关于ruby-on-rails - ruby on Rails : Rails. cache.write 对于特定对象字段数组返回 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16849811/