从YAML加载ActiveRecord对象时出现反序列化错误

tws*_*tws 5 ruby yaml ruby-on-rails delayed-job ruby-on-rails-3

当我尝试反序列化新的ActiveRecord对象时,为什么会出现此错误:

[Dev]> YAML.load(Identity.new.to_yaml)
Delayed::DeserializationError: Delayed::DeserializationError
Run Code Online (Sandbox Code Playgroud)

同时,具有现有AR对象的此示例按预期工作:

[Dev]> YAML.load(Identity.first.to_yaml)
=> #<Identity id: 1, ...
Run Code Online (Sandbox Code Playgroud)

基于搜索答案的一些看似相关的事情:

我使用ruby 1.9.2p318,rails 3.1.3,delayed_job 2.1.4和我YAML::ENGINE.yamlersyck.

我可以做什么,以便我可以将新的身份记录序列化为YAML,然后再将其反序列化?

更新:我还发现,如果我删除了delayed_jobgem,那么这个简单的例子确实有效,而我YAML::ENGINE.yamler现在就是psych.但我delayed_job在我的应用程序中使用,所以了解正在发生的事情仍然很重要

Vir*_*ren 3

那么原因是如果你检查delayed_job结构,就会发现存在一个名为的文件serialization/active_record.rb

现在,对于 Ruby syck(仅 syck 会发生这种情况)作为 YAML 引擎,yaml_new每次调用时都会调用定义YAML.load,如果您从技术上检查该方法,它会尝试从数据库中构建对象,并id从对象的属性中提取内容

所以对于这个

YAML.load(Identity.first.to_yaml)

它在内部执行此操作

Identity.find(1)

但在你的情况下Identity.new,因为没有id与之关联,所以这会让你反序列化

我认为人们花了这么长时间才回答这个问题的原因是你列出的错误

Delayed::DeserializationError: Delayed::DeserializationError

因为它确实声明了当前no primary存在的密钥的任何信息

我相信的原因是这个提交可能是在您发布问题时或多或少同时推送的,但也许您仍在计算机中使用旧代码并没有报告它

ActiveRecord::RecordNotFound, class: #{klass} , primary key: #{val['attributes'][klass.primary_key]} 
Run Code Online (Sandbox Code Playgroud)

笔记 :

它只发生在syck经过测试的pysch情况下,该方法根本没有被调用,也许它用于向后兼容,我猜