serialized.rb 1.5 KB
Newer Older
1 2
module ActiveRecord
  module Type
3
    class Serialized < DelegateClass(ActiveModel::Type::Value) # :nodoc:
4 5
      undef to_yaml if method_defined?(:to_yaml)

6
      include ActiveModel::Type::Helpers::Mutable
7

8
      attr_reader :subtype, :coder
9

10
      def initialize(subtype, coder)
11
        @subtype = subtype
12 13
        @coder = coder
        super(subtype)
14 15
      end

16
      def deserialize(value)
17
        if default_value?(value)
18
          value
19
        else
20
          coder.load(super)
21 22 23
        end
      end

24
      def serialize(value)
25
        return if value.nil?
26
        unless default_value?(value)
27
          super coder.dump(value)
28
        end
29 30
      end

31 32 33 34
      def inspect
        Kernel.instance_method(:inspect).bind(self).call
      end

35 36
      def changed_in_place?(raw_old_value, value)
        return false if value.nil?
37
        raw_new_value = encoded(value)
38 39
        raw_old_value.nil? != raw_new_value.nil? ||
          subtype.changed_in_place?(raw_old_value, raw_new_value)
40 41
      end

42 43 44
      def accessor
        ActiveRecord::Store::IndifferentHashAccessor
      end
45

46 47
      def assert_valid_value(value)
        if coder.respond_to?(:assert_valid_value)
48
          coder.assert_valid_value(value, action: "serialize")
49 50 51
        end
      end

52
      private
53

54 55 56
        def default_value?(value)
          value == coder.load(nil)
        end
57

58 59 60 61
        def encoded(value)
          unless default_value?(value)
            coder.dump(value)
          end
62
        end
63 64 65
    end
  end
end