diff options
Diffstat (limited to 'activerecord/lib/active_record/type/serialized.rb')
-rw-r--r-- | activerecord/lib/active_record/type/serialized.rb | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/type/serialized.rb b/activerecord/lib/active_record/type/serialized.rb new file mode 100644 index 0000000000..4052ac0fa0 --- /dev/null +++ b/activerecord/lib/active_record/type/serialized.rb @@ -0,0 +1,57 @@ +module ActiveRecord + module Type + class Serialized < SimpleDelegator # :nodoc: + attr_reader :subtype, :coder + + def initialize(subtype, coder) + @subtype = subtype + @coder = coder + super(subtype) + end + + def type_cast(value) + if value.respond_to?(:unserialized_value) + value.unserialized_value(super(value.value)) + else + super + end + end + + def type_cast_for_write(value) + Attribute.new(coder, value, :unserialized) + end + + def raw_type_cast_for_write(value) + Attribute.new(coder, value, :serialized) + end + + def serialized? + true + end + + def accessor + ActiveRecord::Store::IndifferentHashAccessor + end + + class Attribute < Struct.new(:coder, :value, :state) # :nodoc: + def unserialized_value(v = value) + state == :serialized ? unserialize(v) : value + end + + def serialized_value + state == :unserialized ? serialize : value + end + + def unserialize(v) + self.state = :unserialized + self.value = coder.load(v) + end + + def serialize + self.state = :serialized + self.value = coder.dump(value) + end + end + end + end +end |