class ViewModel::UpMigrator

def migrate_functional_update!(node, references:)

need to account for it here.
context-dependent meaning. Retrospectively this was a poor choice, but we
The functional update structure uses `_type` internally with a
def migrate_functional_update!(node, references:)
  actions = node[ViewModel::ActiveRecord::ACTIONS_ATTRIBUTE]
  actions&.each do |action|
    action_type = action[ViewModel::TYPE_ATTRIBUTE]
    next unless NESTED_FUPDATE_TYPES.include?(action_type)
    values = action[ViewModel::ActiveRecord::VALUES_ATTRIBUTE]
    values&.each do |value|
      migrate_tree!(value, references: references)
    end
  end
end

def migrate_tree!(node, references:)

def migrate_tree!(node, references:)
  if node.is_a?(Hash) && node[ViewModel::TYPE_ATTRIBUTE] == ViewModel::ActiveRecord::FUNCTIONAL_UPDATE_TYPE
    migrate_functional_update!(node, references: references)
  else
    super
  end
end

def migrate_viewmodel!(view_name, source_version, view_hash, references)

def migrate_viewmodel!(view_name, source_version, view_hash, references)
  path = @paths[view_name]
  return false unless path
  required_version, current_version = @versions[view_name]
  return false if source_version == current_version
  # We assume that an unspecified source version is the same as the required
  # version (i.e. the version demanded by the client request).
  unless source_version.nil? || source_version == required_version
    raise ViewModel::Migration::UnspecifiedVersionError.new(view_name, source_version)
  end
  path.each do |migration|
    migration.up(view_hash, references)
  end
  view_hash[ViewModel::VERSION_ATTRIBUTE] = current_version
  true
end