2010-07-26 52 views
2

我有一个数据库列是一个序列化HashActiveRecord的序列化问题

class Foo < ActiveRecord::Base 
    serialize :bar 
end 

当我保存的酒吧,是几级深的内部哈希,更深层次似乎不正确反序列化时,我需要他们。一级深度的对象得到反序列化就好了。但是,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对象的行为类似原来的对象,但它不是该对象的实际实例?

回答

4

当序列化用户定义的对象而不是“普通的旧Ruby”对象时,需要注意两点。

  • 您需要在对象可以正确地反序列化之前加载用户定义的类,或者实例将是通用的YAML :: Object类型。反序列化不会自动加载类。
  • 某些对象可能无法正确序列化,没有一些自定义,但通常情况并非如此。

一般来说,序列化ActiveRecord :: Base对象的实例是一个坏主意,因为它们的行李数量非常多,除了属性之外,还需要对其进行编码。最好是构建一个直接来自Object的类,这是默认行为,或者来自某种简单的基类。

+1

您可以使用'serialize:attribute,Classname'来确保类在反序列化之前被加载。 – 2012-03-08 23:21:51

+0

我有一个问题,我有一个自定义类的数组 - 解决方案是'需要'custom_class''前'serialize:array_of_classes_field,Array' – you786 2014-01-22 05:07:13