【问题标题】:ActiveRecord serialization problemActiveRecord 序列化问题
【发布时间】:2011-03-21 06:25:59
【问题描述】:

我有一个 db 列,它是一个序列化的Hash

class Foo < ActiveRecord::Base
   serialize :bar
end

当我在 bar 内存储几级深的哈希时,更深的级别在我需要时似乎无法正确反序列化。一层深的对象可以很好地反序列化。但是,2 层或更深的对象仍然是 YAML 类。

我尝试使用 YAML::load() 手动反序列化,但收到错误消息,指出参数不是 IO 实例。

有人知道为什么完整的 Ruby 对象不反序列化吗?

编辑:经过进一步调查,问题似乎源于我从序列化 YAML 中调用虚拟属性这一事实。

class Foo < ActiveRecord::Base
   serialize :bar
end

class Bar < ActiveRecord::Base
    attr_accessor :enabled
end

@bars = @foo.bar[:bars]
@bars.each do |bar|
   puts bar.enabled
end

产量:

NoMethodError: undefined method `enabled' for #<YAML::Object:0xb6f11844>
    from (irb):12
    from (irb):11:in `each'
    from (irb):11
    from :0

这是否意味着反序列化不是“真实的”,即 YAML 对象的行为与原始对象相似,但它不是该对象的实际实例?

【问题讨论】:

    标签: ruby-on-rails ruby serialization activerecord


    【解决方案1】:

    在序列化用户定义的对象而不是“普通的旧 Ruby”对象时,有两点需要牢记。

    • 您需要先加载用户定义的类,然后才能正确反序列化对象,否则实例将属于通用 YAML::Object 类型。反序列化不会自动加载类。
    • 如果不进行一些自定义,某些对象可能无法正确序列化,但通常情况并非如此。

    通常序列化 ActiveRecord::Base 对象的实例是一个坏主意,因为除了您的属性之外,它们还有大量需要编码的包袱。最好构建一个直接从 Object 派生的类,这是默认行为,或者从某种简单的基类派生。

    【讨论】:

    • 您可以使用serialize :attribute, Classname 确保在反序列化之前加载类。
    • 我有一个自定义类数组的问题 - 解决方案是在 require 'custom_class' 之前 serialize :array_of_classes_field, Array
    【解决方案2】:

    这是嵌套 YAML 反序列化的解决方案,以防万一:Ruby on Rails Class Serialize Problem 作者 etienne。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-08
      • 2010-12-12
      • 1970-01-01
      相关资源
      最近更新 更多