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

Code before:
      end

      def association_foreign_key_changed?(reflection, record, key)
        return false if reflection.through_reflection?

        foreign_key = Array(reflection.foreign_key)
        return false unless foreign_key.all? { |key| record._has_attribute?(key) }

        foreign_key.map { |key| record._read_attribute(key) } != Array(key)
      end

      def inverse_polymorphic_association_changed?(reflection, record)
        return false unless reflection.inverse_of&.polymorphic?

        class_name = record._read_attribute(reflection.inverse_of.foreign_type)
        reflection.active_record.polymorphic_name != class_name
      end

      # Saves the associated record if it's new or <tt>:autosave</tt> is enabled.
      #
      # In addition, it will destroy the association if it was marked for destruction.
      def save_belongs_to_association(reflection)
        association = association_instance_get(reflection.name)
        return unless association && association.loaded? && !association.stale_target?

        record = association.load_target
        if record && !record.destroyed?
          autosave = reflection.options[:autosave]

          if autosave && record.marked_for_destruction?
            foreign_key = Array(reflection.foreign_key)
            foreign_key.each { |key| self[key] = nil }
            record.destroy
          elsif autosave != false
            saved = if record.new_record? || (autosave && record.changed_for_autosave?)
              begin
                @autosaving_belongs_to_for ||= {}
                @autosaving_belongs_to_for[association] = true
                record.save(validate: !autosave)
              ensure
                @autosaving_belongs_to_for[association] = false
              end
            end

            if association.updated?
              primary_key = Array(compute_primary_key(reflection, record)).map(&:to_s)
              foreign_key = Array(reflection.foreign_key)

              primary_key_foreign_key_pairs = primary_key.zip(foreign_key)
              primary_key_foreign_key_pairs.each do |primary_key, foreign_key|
                association_id = record._read_attribute(primary_key)

Review comment (suggestion):
Hum, `polymorhpic_class_for` handles the `store_full_class_name` setting. I wonder if this may have an impact here.

Code after:
          saved
        end
      end

      # If the record is new or it has changed, returns true.
      def _record_changed?(reflection, record, key)
        record.new_record? ||
          (association_foreign_key_changed?(reflection, record, key) ||
          inverse_polymorphic_association_changed?(reflection, record)) ||
          record.will_save_change_to_attribute?(reflection.foreign_key)
      end

      def association_foreign_key_changed?(reflection, record, key)
        return false if reflection.through_reflection?

        foreign_key = Array(reflection.foreign_key)
        return false unless foreign_key.all? { |key| record._has_attribute?(key) }

        foreign_key.map { |key| record._read_attribute(key) } != Array(key)
      end

      def inverse_polymorphic_association_changed?(reflection, record)
        return false unless reflection.inverse_of&.polymorphic?

        class_name = record._read_attribute(reflection.inverse_of.foreign_type)
        reflection.active_record.polymorphic_name != class_name
      end

      # Saves the associated record if it's new or <tt>:autosave</tt> is enabled.
      #
      # In addition, it will destroy the association if it was marked for destruction.
      def save_belongs_to_association(reflection)
        association = association_instance_get(reflection.name)
        return unless association && association.loaded? && !association.stale_target?

        record = association.load_target
        if record && !record.destroyed?
          autosave = reflection.options[:autosave]

          if autosave && record.marked_for_destruction?
            foreign_key = Array(reflection.foreign_key)
            foreign_key.each { |key| self[key] = nil }
            record.destroy
          elsif autosave != false
            saved = if record.new_record? || (autosave && record.changed_for_autosave?)
              begin
                @autosaving_belongs_to_for ||= {}
                @autosaving_belongs_to_for[association] = true
                record.save(validate: !autosave)
              ensure
                @autosaving_belongs_to_for[association] = false