Rails类方法中底层缓存的使用及缓存失效问题排查
Rails类方法中使用底层缓存及缓存不生效问题排查
一、Rails类方法中使用底层缓存的常规方式
- 直接调用
Rails.cache.fetch,传入唯一缓存键和缓存配置(如过期时间),缓存块内编写需要缓存的业务逻辑 - 缓存键需包含所有影响结果的变量(比如示例中的
da_code、I18n.locale),确保不同参数/场景对应独立的缓存条目 - 注意缓存块的返回值:
fetch会将块的最终返回值存入缓存,因此要保证块能正确返回预期结果
二、你的缓存不生效的原因及修复
你的代码存在核心问题:在缓存块内使用了return语句,导致Rails.cache.fetch无法捕获块的返回值并写入缓存,最终每次调用都会执行数据库查询。
问题分析
Rails.cache.fetch的逻辑是:缓存命中则直接返回值;未命中则执行块内代码,将块的最后一行返回值存入缓存。但你在块中用了return option.title if option,这会直接跳出整个类方法,而非把值返回给fetch方法,导致缓存永远无法被写入。
修复后的代码
# in an ActiveRecord model.... def self.label(da_code) Rails.cache.fetch [:option, :label, da_code, I18n.locale], expires_in: 3.hours do option = Option.i18n.find_by(code: da_code) option ? option.title : da_code end end
额外注意事项
- 开发模式下需确认已开启缓存:可通过
rails dev:cache命令切换,或在config/environments/development.rb中设置config.cache_store = :memory_store(默认开发模式为:null_store,不会实际存储缓存) - 由于使用Mobility做国际化,你的缓存键已包含
I18n.locale,能保证不同语言版本的缓存独立,这部分是正确的 - 可通过
Rails.cache.read([:option, :label, '目标code', I18n.locale])手动检查缓存是否成功写入,验证修复效果
内容的提问来源于stack exchange,提问作者croceldon
相关产品推荐
相关产品推荐

