rails 3.2.2无法反序列化序列化模型对象 - 奇怪的行为

时间:2012-08-01 18:04:52

标签: ruby-on-rails activerecord deserialization

我为这个漫长/复杂的问题道歉。

使用rails 3.2.2(ruby 1.9.3-p194),我们使用Dalli / memcached为会话存储将特定于用户的ActiveRecord模型对象保存到会话中,并且在开发期间,我们有时会在从中检索数据时看到错误会议:

ArgumentError (Unable to unmarshal value: dump format error for symbol(0x46)):

通常,当数据出现问题时会发生错误(例如,对象的外键指向不存在的记录)。

但是,每当我们添加或删除涉及多对多关联的记录时,我们仍然会收到此错误,即使所有外键都有效且一切似乎都正确(在吹走数据库,查杀rails和memcache服务器之后)等等。)。

使用连接表和has_many-through实现多对多关联。我们架构的高度简化视图是:

  User
   |
 Profile
  |  \
  .   \
  .    \
  .     \
  |      \
 Foo ==== Bar

如果用户有很多个人资料,个人资料有很多Foos(间接地,通过其他表格),个人资料有很多个条,而Foos和酒吧通过BarFoo联接表互相拥有很多。

在向条形图添加/删除Foo时通常会触发错误。虽然我们在从会话中检索时已经意识到它,但会话/内存缓存本身并不是罪魁祸首,因为即使在数据存储在会话中之前也可能强制发生错误。

为了从等式中消除会话,我在创建/删除Foo / Bar记录之后插入了这段代码:

Marshal.load(Marshal.dump(user)) # throws exception first time

这会引发异常。真正令人费解的是:如果我捕获异常以便继续处理请求,那么用户对象实际上存储在会话中,并且在之后没有问题之后被提取。 (我发现这一点是因为在调试断点期间,运行上面的代码一旦失败,立即再次运行成功并在执行继续时“修复”问题。)

更奇怪的是,如果不是上面的代码,我会立即创建/删除Foo / Bar:

Marshal.load(Marshal.dump(profile)) # does not throw any exception

我完全没有例外,其余的代码都可以工作(用户可以从会话中存储和检索而没有错误)。

我已经阅读了很多讨论,似乎说AR模型实例不应该被缓存,因为它们可能包含procs,IO等。但是,在转储对象时我们没有得到TypeErrors。通过在User模型上运行两次序列化/反序列化或在其子模型上运行一次来​​“纠正”问题的事实非常令人费解。一个对象的序列化表示如何在一个时刻无效并且对下一个有效?

有人能告诉我这是否是rails中的错误?或者我们正在做一些不受支持的事情?有没有办法用它们的相关模型序列化模型对象,还是我必须为模型对象及其关联实现我自己的序列化/反序列化代码?

更新:此错误不仅限于多对多关联。在创建/更新/删除模式中的其他表时也会发生这种情况,但在这些情况下,它更加罕见且几乎不可能重现。

0 个答案:

没有答案