2010-07-26 4 views
2

직렬화 문제 Hash 직렬화 A : 몇 수준 깊은 바의 내부 해시를 저장할 때액티브 내가있는 DB 열이

class Foo < ActiveRecord::Base 
    serialize :bar 
end 

이 깊은 수준이하지 않는 것 제대로 할 때 역 직렬화하는 I 그것들이 필요하다. 한 레벨 깊이의 객체는 잘 디 직렬화됩니다. 그러나 2 레벨 이상의 오브젝트는 YAML 클래스로 깊이 남아 있습니다.

YAML :: load()를 사용하여 수동으로 deserialize를 시도했지만 인수가 IO의 인스턴스가 아니라는 오류가 발생했습니다.

완전한 루비 객체가 왜 비 직렬화되지 않는지 아는 사람이 있습니까?

EDIT : 추가 조사를 마친 후에는 직렬화 된 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

"일반 오래된 루비"객체 대신 사용자 정의 객체를 직렬화 할 때 유의해야 할 두 가지 사항이 있습니다.

  • 개체가 올바르게 직렬화 해제되기 전에 사용자 정의 클래스를로드해야합니다. 그렇지 않으면 인스턴스가 일반 YAML :: Object 형식이됩니다. 직렬화 해제는 클래스를 자동로드하지 않습니다.
  • 일부 개체는 일부 사용자 지정 작업없이 제대로 serialize되지 않을 수 있지만 일반적으로 그렇지 않습니다.

일반적으로 ActiveRecord :: Base 객체의 인스턴스를 직렬화하는 것은 속성과 함께 인코딩해야하는 엄청난 양의 수하물을 가지고 있기 때문에 나쁜 생각입니다. 기본 동작 인 Object에서 직접 파생 된 클래스를 작성하거나 일종의 간단한 기본 클래스에서 빌드하는 것이 가장 좋습니다.

+1

'serialize : attribute, Classname'을 사용하여 클래스가 직렬화 복원 전에로드되는지 확인할 수 있습니다. –

+0

배열에 사용자 정의 클래스가있는 문제가있었습니다. 해결책은 'serialize하기 전에 custom_class'가 필요합니다 : array_of_classes_field, Array' – you786