aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/type/serialized.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/type/serialized.rb')
-rw-r--r--activerecord/lib/active_record/type/serialized.rb57
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