module ViewModel::ActiveRecord::AssociationManipulation
def replace_associated(association_name, update_hash, references: {}, deserialize_context: self.class.new_deserialize_context)
def replace_associated(association_name, update_hash, references: {}, deserialize_context: self.class.new_deserialize_context) association_data = self.class._association_data(association_name) # TODO: structure checking if association_data.through? || association_data.shared? is_fupdate = association_data.collection? && update_hash.is_a?(Hash) && update_hash[ViewModel::ActiveRecord::TYPE_ATTRIBUTE] == ViewModel::ActiveRecord::FUNCTIONAL_UPDATE_TYPE if is_fupdate update_hash[ViewModel::ActiveRecord::ACTIONS_ATTRIBUTE].each_with_index do |action, i| action_type_name = action[ViewModel::ActiveRecord::TYPE_ATTRIBUTE] if action_type_name == ViewModel::ActiveRecord::FunctionalUpdate::Remove::NAME # Remove actions are always type/id refs; others need to be translated to proper refs next end association_references = convert_updates_to_references( action[ViewModel::ActiveRecord::VALUES_ATTRIBUTE], key: "#{action_type_name}_#{i}") references.merge!(association_references) action[ViewModel::ActiveRecord::VALUES_ATTRIBUTE] = association_references.each_key.map { |ref| { ViewModel::REFERENCE_ATTRIBUTE => ref } } end else update_hash = ViewModel::Utils.wrap_one_or_many(update_hash) do |sh| association_references = convert_updates_to_references(sh, key: 'replace') references.merge!(association_references) association_references.each_key.map { |ref| { ViewModel::REFERENCE_ATTRIBUTE => ref } } end end end root_update_hash = { ViewModel::ID_ATTRIBUTE => self.id, ViewModel::TYPE_ATTRIBUTE => self.class.view_name, association_name.to_s => update_hash, } root_update_viewmodel = self.class.deserialize_from_view(root_update_hash, references: references, deserialize_context: deserialize_context) root_update_viewmodel._read_association(association_name) end