To enable this, override and return getRelationWidget().
@param \yii\db\ActiveRecord $model
@param string $relation
@param \yii\db\ActiveQuery $activeRelation
@return ActiveField
775793
protected static function getHasManyRelationField($model, $relation, $activeRelation)
    {
        $widgetOptions = self::getRelationWidgetOptions($model, $relation, $activeRelation, true);
        return static::getRelationWidget($model, $relation, $activeRelation, $widgetOptions);
    }
961614
protected function getNullForeignKeyFromRelation(string $relation): array
    {
        $key = $this->entityMap->getLocalKeys($relation);

        if (is_array($key)) {
            return $this->entityMap->getEmptyValueForLocalKey($relation);
        }

        if (is_null($key)) {
            throw new MappingException("Foreign key for relation $relation cannot be null");
        }

        return [
            $key => $this->entityMap->getEmptyValueForLocalKey($relation),
        ];
    }
390805
public function edgeFromRelationWithDirection(Relationship $relation, Model $parent, Model $related, $direction)
    {
        // If the direction is of type 'any' we need to figure out the relationship direction
        // from the determined relation.
        if ($direction == 'any')
        {
            $direction = $this->directionFromRelation($relation, $parent, $related);
        }

        // Based on the direction we are now able to construct the edge class name and call for
        // an instance of it then pass it the actual relationship that was previously found.
        $class = $this->getEdgeClass($direction);
        $edge = new $class($this->query, $parent, $related, $relation->getType());
        $edge->setRelation($relation, true);

        return $edge;
    }
662677
public static function buildSelectRelation($relation, $mapperRelation) {
        $query = "";

        $fields = "";
        foreach ($mapperRelation->getPropertys() as $property) {
            $fields .= "c." . $property->getColumn() . ", ";
        }
        $fields = substr_replace($fields, "", -2);

        if ($relation->getCardinality() == Relation::$manyToMany) {
            $query = "select " . $fields . " from " . $mapperRelation->getTable() . " c ";
            $query .= "inner join " . $relation->getTable() . " nc on nc." . $relation->getForeignColumn() . " = c.id ";
            $query .= "where nc." . $relation->getLocalColumn() . " = :id";
        }
        if ($relation->getCardinality() == Relation::$oneToMany) {
            $query = "select " . $fields . " from " . $mapperRelation->getTable() . " c ";
            $query .= "where c." . $relation->getForeignColumn() . " = :id";
        }
        return $query;
    }
876924
protected function getRelationCondition($relation, $value)
    {
        /** @var \yii\db\ActiveRecord $relationClass */
        $relationClass = $relation->modelClass;
        if ($relation->via !== null) {
            /* @var $viaRelation \yii\db\ActiveQuery */
            $viaRelation = is_array($relation->via) ? $relation->via[1] : $relation->via;
            /** @var \yii\db\ActiveRecord $viaClass */
            $viaClass = $viaRelation->modelClass;
            $subquery = (new Query)
                ->select(array_map(function ($key) {
                    return 'j.' . $key;
                }, array_keys($viaRelation->link)))
                ->from(['t' => $relationClass::tableName()])
                ->innerJoin(['j' => $viaClass::tableName()], implode(' AND ', array_map(function ($leftKey, $rightKey) {
                    return 't.' . $leftKey .' = j.' . $rightKey;
                }, array_keys($relation->link), array_values($relation->link))))
                ->where(['IN', array_map(function ($key) {
                    return 't.' . $key;
                }, $relationClass::primaryKey()), $value]);
            $linkKeys = array_values($viaRelation->link);
        } else {
            $subquery = (new Query)
                ->select(array_keys($relation->link))
                ->from(['t' => $relationClass::tableName()])
                ->where(['IN', array_map(function ($key) {
                    return 't.' . $key;
                }, $relationClass::primaryKey()), $value]);
            $linkKeys = array_values($relation->link);
        }
        return ['IN', array_map(function ($key) {
            return 't.' . $key;
        }, $linkKeys), $subquery];
    }
152791
protected static function getRelationColumn($model, $field, $relation)
    {
        return [
            'attribute' => $field,
            'format'    => 'text',
            'visible'   => true,
            'label'     => $model->getRelationLabel($relation, $field),
        ];
    }
1302235
public function getRelationTableName($relation) {
        $relationTable  = !empty($this->tablePrefix) ? $this->tablePrefix : '';
        $relationTable .= $this->tableName?$this->tableName:$this->name;
        $relationTable .= '_'.$relation->getModelName();
        return strtolower($relationTable);
    }
1285819
public static function buildRelationQuery($entity, Relation $relation) {
        $relQuery = "";
        $getid = "getId";
        if ($relation->getCardinality() == Relation::$manyToMany) {
            $m = "get" . $relation->getName();
            $relQuery .= "INSERT INTO " . $relation->getTable() . " (" . $relation->getLocalColumn() . ", " . $relation->getForeignColumn() . ") ";
            $relQuery .= "VALUES (:" . $relation->getLocalColumn() . ", :" . $relation->getForeignColumn() . ");";
        }
        if ($relation->getCardinality() == Relation::$oneToMany) {
            $relMapper = MapperBuilder::buildFromName($this->mapping, $relation->getEntity());
            $m = "get" . $relation->getName();
            foreach ($entity->$m() as $rel) {
                $setid = "set" . $relMapper->getNameForColumn($relation->getForeignColumn());
                $rel->$setid($entity->$getid());
                $relQuery .= $this->buildInsertQuery($rel);
            }
        }


        return $relQuery;
    }
86577
public function with($relation)
    {
        $this->reset();

        if (func_num_args() > 1) {
            return $this->with(func_get_args());
        }

        if (is_array($relation)) {
            $this->related = array_merge($this->related, $relation);
        } else {
            $this->related[] = $relation;
        }

        $this->relatedCount = count($this->related);

        return $this;
    }
519739
protected function eagerlyMorphToOne($model, $relation, &$result, $subRelation = '')
    {
        // 预载入关联查询 支持嵌套预载入
        $pk   = $this->parent->{$this->morphKey};
        $data = (new $model)->with($subRelation)->find($pk);

        if ($data) {
            $data->setParent(clone $result);
            $data->isUpdate(true);
        }

        $result->setRelation(Db::parseName($relation), $data ?: null);
    }
501715
public function with($relation)
    {
        foreach ((array) $relation as $node) {
            $instance = $this->factory->build($this->model(), $node);
            $this->relations[$instance->name()] = $instance;
        }

        return $this;
    }
283697
protected function validateRelationModel($prettyRelationName, $relationName, BaseActiveRecord $relationModel)
    {
        /** @var BaseActiveRecord $model */
        $model = $this->owner;
        if (!is_null($relationModel) && ($relationModel->isNewRecord || count($relationModel->getDirtyAttributes()))) {
            Yii::debug("Validating {$prettyRelationName} relation model using " . $relationModel->scenario . ' scenario', __METHOD__);
            if (!$relationModel->validate()) {
                $this->_addError($relationModel, $model, $relationName, $prettyRelationName);
            }

        }
    }
562837
public function getCmsSpecialRelationType($relation)
    {
        if (    ! array_key_exists($relation, $this->relationsConfig)
            ||  ! array_key_exists('type', $this->relationsConfig[$relation])
        ) {
            return null;
        }

        return $this->relationsConfig[ $relation ]['type'];
    }
113564
public function hasMany($model, $serializer, $relation = null)
    {
        return $this->buildRelationship($model, $serializer, $relation, true);
    }
789311
public function getRelation($relation)
    {
        $query = Relation::noConstraints(function() use ($relation)
        {
            return $this->getModel()->$relation();
        });

        $nested = $this->nestedRelations($relation);

        if (count($nested) > 0) {
            $query->getQuery()->with($nested);
        }

        return $query;
    }
1091179
public static function related_class($relation)
	{
		$class = get_called_class();

		foreach (static::$_valid_relations as $rel_name => $rel_class)
		{
			if (property_exists($class, '_'.$rel_name))
			{
				if (isset(static::${'_'.$rel_name}[$relation]))
				{
					return static::${'_'.$rel_name}[$relation]['model_to'];
				}
			}
		}

		return null;
	}
504859
protected function joinEagerLoadedColumn($relation, $relationColumn)
    {
        $joins = [];
        foreach ((array) $this->getQueryBuilder()->joins as $key => $join) {
            $joins[] = $join->table;
        }

        $model = $this->query->getRelation($relation);
        if ($model instanceof BelongsToMany) {
            $pivot   = $model->getTable();
            $pivotPK = $model->getForeignKey();
            $pivotFK = $model->getQualifiedParentKeyName();

            if (!in_array($pivot, $joins)) {
                $this->getQueryBuilder()->leftJoin($pivot, $pivotPK, '=', $pivotFK);
            }

            $related = $model->getRelated();
            $table   = $related->getTable();
            $tablePK = $related->getForeignKey();
            $tableFK = $related->getQualifiedKeyName();

            if (!in_array($table, $joins)) {
                $this->getQueryBuilder()->leftJoin($table, $pivot . '.' . $tablePK, '=', $tableFK);
            }
        } else {
            $table   = $model->getRelated()->getTable();
            $foreign = $model->getQualifiedForeignKey();
            $other   = $model->getQualifiedOtherKeyName();
            if (!in_array($table, $joins)) {
                $this->getQueryBuilder()->leftJoin($table, $foreign, '=', $other);
            }
        }

        $column = $table . '.' . $relationColumn;

        return $column;
    }