Ruby on Rails 序列化然后反序列化 JSON 中的同一个对象

Posted

技术标签:

【中文标题】Ruby on Rails 序列化然后反序列化 JSON 中的同一个对象【英文标题】:Ruby on Rails serialize and then deserialize the same object in JSON 【发布时间】:2011-05-10 21:48:45 【问题描述】:

我花了几天的时间尝试所有的 JSON 库,包括 JSON gem、Yajl-ruby、ActiveSupport::JSON,但没有什么可以做这个简单的任务:

user = User.find(1)
json = user.to_json
user2 = json.as_json # OR json.from_json 
                     # OR JSON.parse(json) 
                     # OR Yajl::Parser.parse(json)
                     # OR ActiveSupport::JSON.decode(json)

当我尝试使用反序列化的 JSON 数据创建新用户时,我收到以下错误之一:

User.new(Yajl::Parser.parse(json))  
# ActiveRecord::UnknownAttributeError: unknown attribute: json_class

User.new(json.as_json)
# NoMethodError: undefined method `stringify_keys!' for #<String:0xb6de4318>

User.new(JSON.parse(json))
# NoMethodError: undefined method `stringify_keys!' for #<User:0xb6dc7470>

User.new(ActiveSupport::JSON.decode(json))
# NoMethodError: undefined method `stringify_keys!' for #<User:0xb6da3764>

使用 to_yaml 和 from_yaml 使用 YAML 很容易做到这一点。为什么 to_json 不能生成 from_json 可以转换回 ruby​​ 对象的那种 JSON?

编辑:我使用的是 Rails 2.3.8,虽然我尝试过 2.3.5 和 3.0.0。另外,我正在使用 json-rpc 插件来创建 JSON-RPC 服务,尽管没有插件时同样的问题仍然存在。

【问题讨论】:

你确定你的 json 是真的 json 吗?就错误而言,它似乎更像是用户对象:( 【参考方案1】:
json = Episode.first.to_json
dec = ActiveSupport::JSON.decode json
Episode.new dec['episode']

在 Rails 3.0.1 中为我工作。在您的示例中,在将 JSON 转换回 Ruby 后,您没有从包装器 dict 中取出实际属性 dict。你应该试试

User.new(ActiveSupport::JSON.decode(json)['user'])

【讨论】:

是的,这应该可以。另一个选项,仅序列化属性:User.first.attributes.to_json。 仅序列化属性有效。 User.new(ActiveSupport::JSON.decode(json)['user']) 没有。 json 存储为字符串,解码后是一个具有空属性的用户对象。 User.new(ActiveSupport::JSON.decode(json)['attributes']) 在 Rails 3 中工作。

以上是关于Ruby on Rails 序列化然后反序列化 JSON 中的同一个对象的主要内容,如果未能解决你的问题,请参考以下文章

Ruby on Rails 高级 JSON 序列化

Ruby on Rails JSON 序列化

Ruby On Rails 中的编组与 ActiveRecord 序列化

使用 Ruby on Rails 从数据库中的 yaml 序列化字段中获取大小数

Ruby on Rails - 来自 Paypal 的参数:utf-8 中的无效字节序列

Ruby on Rails“由于bot而导致的UTF-8中无效的字节序列”