Repository: rails/rails
File: activerecord/lib/active_record/store.rb (Ruby)

Code before:
        end

        def self.init(object, attribute)
          store_object = {}
          object.public_send :"#{attribute}=", store_object
          store_object
        end
      end

      class StringKeyedHashAccessor < HashAccessor # :nodoc:
        def self.get(store_object, key)
          super store_object, Symbol === key ? key.name : key.to_s
        end

        def self.read(object, attribute, key)
          super object, attribute, Symbol === key ? key.name : key.to_s
        end

        def self.write(object, attribute, key, value)
          super object, attribute, Symbol === key ? key.name : key.to_s, value
        end
      end

      class IndifferentHashAccessor < ActiveRecord::Store::HashAccessor # :nodoc:
        def self.init(object, store_attribute)
          attribute = object.send(store_attribute)
          unless attribute.is_a?(ActiveSupport::HashWithIndifferentAccess)
            attribute = IndifferentCoder.as_indifferent_hash(attribute)
            object.public_send :"#{store_attribute}=", attribute
          end
          attribute
        end
      end

      class IndifferentCoder # :nodoc:
        def initialize(attr_name, coder_or_class_name)
          @coder =
            if coder_or_class_name.respond_to?(:load) && coder_or_class_name.respond_to?(:dump)
              coder_or_class_name
            else
              ActiveRecord::Coders::YAMLColumn.new(attr_name, coder_or_class_name || Object)
            end
        end

        def dump(obj)
          @coder.dump as_regular_hash(obj)
        end

        def load(yaml)
          self.class.as_indifferent_hash(@coder.load(yaml || ""))
        end

Review comment (suggestion):
Didn't this change behavior? Previously this would have converted `attribute` from Hash to ActiveSupport::HashWithIndifferentAccess, but now this will only be called if `attribute` is nil.

Code after:
        end

        def self.prepare(object, attribute)
          store_object = object.public_send(attribute)

          if store_object.nil?
            store_object = {}
            object.public_send(:"#{attribute}=", store_object)
          end

          store_object
        end
      end

      class StringKeyedHashAccessor < HashAccessor # :nodoc:
        def self.get(store_object, key)
          super store_object, Symbol === key ? key.name : key.to_s
        end

        def self.read(object, attribute, key)
          super object, attribute, Symbol === key ? key.name : key.to_s
        end

        def self.write(object, attribute, key, value)
          super object, attribute, Symbol === key ? key.name : key.to_s, value
        end
      end

      class IndifferentHashAccessor < ActiveRecord::Store::HashAccessor # :nodoc:
        def self.prepare(object, attribute)
          store_object = object.public_send(attribute)

          unless store_object.is_a?(ActiveSupport::HashWithIndifferentAccess)
            store_object = IndifferentCoder.as_indifferent_hash(store_object)
            object.public_send :"#{attribute}=", store_object
          end

          store_object
        end
      end

      class IndifferentCoder # :nodoc:
        def initialize(attr_name, coder_or_class_name)
          @coder =
            if coder_or_class_name.respond_to?(:load) && coder_or_class_name.respond_to?(:dump)
              coder_or_class_name
            else
              ActiveRecord::Coders::YAMLColumn.new(attr_name, coder_or_class_name || Object)
            end
        end