Имам 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.