Rails/ActiveRecord 版本之间的元帅冲突

问题描述

我正在尝试同时运行 Rails 5 和 Rails 6,但在项目的 Rails 5 和 6 版本共享相同的外部缓存时遇到了缓存问题。铁轨之后 项目的5版本缓存了一个ActiveRecord对象,当Rails 6版本从缓存中读取并尝试读取cached_object.id时,它返回nil。有趣的是,cached_object[:id] 返回了正确的值。

我们的缓存实现在幕后使用 Marshal 进行序列化/反序列化,因此我能够在不依赖缓存的情况下重现这一点,如下所示:

给定一个运行 Rails 5 的项目:

usr = User.find_by_id(1)
puts Marshal.dump(usr)

Marshal.dump 的结果复制并粘贴到另一个运行 Rails 6 的控制台:

usr = Marshal.load(<copY_PASTE_STRING>)
usr.id // returns nil
usr[:id] // returns 1

相反的情况似乎并非如此(即,Rails 6 中的 Marshal.dump 和 Rails 5 中的 Marshal.load 没有重现这一点)

是否有人熟悉 Rails 内部结构,可能知道这里发生了什么?

解决方法

事实证明,这种行为不是 Marshal 的问题,而是 Rails 6 中 ActiveRecord 的 change