module ViewModel::ActiveRecord::AssociationManipulation

def append_associated(association_name, subtree_hash_or_hashes, references: {}, before: nil, after: nil, deserialize_context: self.class.new_deserialize_context)

at the end.
collection, the items are inserted either before `before`, after `after`, or
Create or update members of a associated collection. For an ordered
def append_associated(association_name, subtree_hash_or_hashes, references: {}, before: nil, after: nil, deserialize_context: self.class.new_deserialize_context)
  if self.changes.changed?
    raise ArgumentError.new('Invalid call to append_associated on viewmodel with pending changes')
  end
  association_data = self.class._association_data(association_name)
  direct_reflection = association_data.direct_reflection
  raise ArgumentError.new("Cannot append to single association '#{association_name}'") unless association_data.collection?
  ViewModel::Utils.wrap_one_or_many(subtree_hash_or_hashes) do |subtree_hashes|
    model_class.transaction do
      ViewModel::Callbacks.wrap_deserialize(self, deserialize_context: deserialize_context) do |hook_control|
        association_changed!(association_name)
        deserialize_context.run_callback(ViewModel::Callbacks::Hook::BeforeValidate, self)
        if association_data.through?
          raise ArgumentError.new('Polymorphic through relationships not supported yet') if association_data.polymorphic?
          direct_viewmodel_class = association_data.direct_viewmodel
          root_update_data, referenced_update_data = construct_indirect_append_updates(association_data, subtree_hashes, references)
        else
          raise ArgumentError.new('Polymorphic STI relationships not supported yet') if association_data.polymorphic?
          direct_viewmodel_class = association_data.viewmodel_class
          root_update_data, referenced_update_data = construct_direct_append_updates(association_data, subtree_hashes, references)
        end
        update_context = ViewModel::ActiveRecord::UpdateContext.build!(root_update_data, referenced_update_data, root_type: direct_viewmodel_class)
        # Set new parent
        new_parent = ViewModel::ActiveRecord::UpdateOperation::ParentData.new(direct_reflection.inverse_of, self)
        update_context.root_updates.each { |update| update.reparent_to = new_parent }
        # Set place in list.
        if association_data.ordered?
          new_positions = select_append_positions(association_data,
                                                  direct_viewmodel_class._list_attribute_name,
                                                  update_context.root_updates.count,
                                                  before: before, after: after)
          update_context.root_updates.zip(new_positions).each do |update, new_pos|
            update.reposition_to = new_pos
          end
        end
        # Because append_associated can take from other parents, edit-check previous parents (other than this model)
        unless association_data.through?
          inverse_assoc_name = direct_reflection.inverse_of.name
          previous_parent_ids = Set.new
          update_context.root_updates.each do |update|
            update_model    = update.viewmodel.model
            parent_model_id = update_model.read_attribute(update_model
                                                            .association(inverse_assoc_name)
                                                            .reflection.foreign_key)
            if parent_model_id && parent_model_id != self.id
              previous_parent_ids << parent_model_id
            end
          end
          if previous_parent_ids.present?
            previous_parents = self.class.find(previous_parent_ids.to_a, eager_include: false)
            previous_parents.each do |parent_view|
              ViewModel::Callbacks.wrap_deserialize(parent_view, deserialize_context: deserialize_context) do |pp_hook_control|
                changes = ViewModel::Changes.new(changed_associations: [association_name])
                deserialize_context.run_callback(ViewModel::Callbacks::Hook::OnChange, parent_view, changes: changes)
                pp_hook_control.record_changes(changes)
              end
            end
          end
        end
        child_context = self.context_for_child(association_name, context: deserialize_context)
        updated_viewmodels = update_context.run!(deserialize_context: child_context)
        # Propagate changes and finalize the parent
        updated_viewmodels.each do |child|
          child_changes = child.previous_changes
          if association_data.nested?
            nested_children_changed!     if child_changes.changed_nested_tree?
            referenced_children_changed! if child_changes.changed_referenced_children?
          elsif association_data.owned?
            referenced_children_changed! if child_changes.changed_owned_tree?
          end
        end
        final_changes = self.clear_changes!
        if association_data.through?
          updated_viewmodels.map! do |direct_vm|
            direct_vm._read_association(association_data.indirect_reflection.name)
          end
        end
        # Could happen if hooks attempted to change the parent, which aren't
        # valid since we're only editing children here.
        unless final_changes.contained_to?(associations: [association_name.to_s])
          raise ViewModel::DeserializationError::InvalidParentEdit.new(final_changes, blame_reference)
        end
        deserialize_context.run_callback(ViewModel::Callbacks::Hook::OnChange, self, changes: final_changes)
        hook_control.record_changes(final_changes)
        updated_viewmodels
      end
    end
  end
end