/ / ActiveRecord сериализация проблем - рубинка на релси, рубин, сериализация, activerecord

Проблем със сериализацията ActiveRecord - рубин на релси, рубин, сериализация, активен запис

Имам db колона, която е сериализирана Hash:

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 за отговор № 1

Има две неща, които трябва да имате предвид, когато сериализирате дефинирани от потребителя обекти вместо "обикновени стари Ruby" обекти.

  • Трябва да имате натоварени от потребителя класове, преди обектът да бъде правилно десерилизиран или инстанциите да бъдат с общ тип YAML :: Object. Десериализирането не води до автоматично зареждане на класове.
  • Възможно е някои обекти да не сериализират правилно, без да са персонализирани, въпреки че това обикновено не е така.

По принцип сериализиращи случаи наActiveRecord :: Base обект е лоша идея, тъй като те имат извънредно количество багаж, който ще трябва да бъде кодиран в допълнение към вашия атрибут. Най-добре е да се изгради клас, който се получава директно от обекта, което е по подразбиране поведение или от обикновен базов клас от някакъв вид.


1 за отговор № 2

Това е решение за внедряване на YAML десериализацията в случай, че тя помага: Ruby on Rails клас сериализира проблема от автора etienne.