class ViewModel::ActiveRecord::AssociationData

def lazy_initialize!

def lazy_initialize!
  @mutex.synchronize do
    return if @initialized
    if through?
      intermediate_model   = @direct_reflection.klass
      @indirect_reflection = load_indirect_reflection(intermediate_model, @indirect_association_name)
      target_reflection    = @indirect_reflection
    else
      target_reflection = @direct_reflection
    end
    @viewmodel_classes =
      if @target_viewmodels.present?
        # Explicitly named
        @target_viewmodels.map { |v| resolve_viewmodel_class(v) }
      else
        # Infer name from name of model
        if target_reflection.polymorphic?
          raise InvalidAssociation.new(
                  'Cannot automatically infer target viewmodels from polymorphic association')
        end
        infer_viewmodel_class(target_reflection.klass)
      end
    @referenced = @viewmodel_classes.first.root?
    # Non-referenced viewmodels must be owned. For referenced viewmodels, we
    # own it if it points to us. Through associations aren't considered
    # `owned?`: while we do own the implicit direct viewmodel, we don't own
    # the target of the association.
    @owned = !@referenced || (target_reflection.macro != :belongs_to)
    unless @viewmodel_classes.all? { |v| v.root? == @referenced }
      raise InvalidAssociation.new('Invalid association target: mixed root and non-root viewmodels')
    end
    if external? && !@referenced
      raise InvalidAssociation.new('External associations must be to root viewmodels')
    end
    if through?
      unless @referenced
        raise InvalidAssociation.new('Through associations must be to root viewmodels')
      end
      @direct_viewmodel = build_direct_viewmodel(@direct_reflection, @indirect_reflection,
                                                 @viewmodel_classes, @through_order_attr)
    end
    @initialized = true
  end
end