Rails Rails 6.1 升级到 7 的一个迷之错误,居然是缓存导致的 :)

hegwin · 2022年11月24日 · 131 次阅读

从 Rails 6.1 升到 7 的时候,有仔细读过 ugprade guideline,但还是在部署之后遇到了一个很奇妙的错误,霸占了 Sentry…

ActionView::Template::Error
The :mode option must be one of [:all, :n_plus_one_only].

strict_loading是 6.1 加的一个功能,用来检测 N+1 query 的,但是当时直接忽略了它,默认全局关闭,因为有用别的 gem 做了这件事。。

等到了 7 遇到这个错误,尝试 debug 还翻到了这个错误的源码所在地,总之非常不理解:

# activerecord/lib/active_record/core.rb
def strict_loading!(value = true, mode: :all)
  unless [:all, :n_plus_one_only].include?(mode)
    raise ArgumentError, "The :mode option must be one of [:all, :n_plus_one_only] but #{mode.inspect} was provided."
  end

  @strict_loading_mode = mode
  @strict_loading = value
end

最终没有在 stack overflow 找到原因,而是在 rails 的 PR 里看到了这条 comment

解决方法是:清理掉 rails 的缓存就可以了。

猜测原因可能是在 view 里缓存了一部分 active records,而这些缓存是在升 7 之前缓存的…当从缓存里拿出来这些 ActiveRecord[] 的时候,它们没有 mode 这个属性,于是就报错了。

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请 注册新账号