0 follower

Class Yiisoft\ActiveRecord\ActiveQuery

InheritanceYiisoft\ActiveRecord\ActiveQuery » Yiisoft\Db\Query\Query
ImplementsYiisoft\ActiveRecord\ActiveQueryInterface

Represents a db query associated with an Active Record class.

An ActiveQuery can be a normal query or be used in a relational context.

ActiveQuery instances are usually created by {@see \Yiisoft\ActiveRecord\findOne()}, {@see \Yiisoft\ActiveRecord\findBySql()}, {@see \Yiisoft\ActiveRecord\findAll()}.

Relational queries are created by {@see \Yiisoft\ActiveRecord\ActiveRecord::hasOne()} and {@see \Yiisoft\ActiveRecord\ActiveRecord::hasMany()}.

Normal Query

ActiveQuery mainly provides the following methods to retrieve the query results:

  • {@see \Yiisoft\ActiveRecord\one()}: returns a single record populated with the first row of data.
  • {@see \Yiisoft\ActiveRecord\all()}: returns all records based on the query results.
  • {@see \Yiisoft\ActiveRecord\count()}: returns the number of records.
  • {@see \Yiisoft\ActiveRecord\sum()}: returns the sum over the specified column.
  • {@see \Yiisoft\ActiveRecord\average()}: returns the average over the specified column.
  • {@see \Yiisoft\ActiveRecord\min()}: returns the min over the specified column.
  • {@see \Yiisoft\ActiveRecord\max()}: returns the max over the specified column.
  • {@see \Yiisoft\ActiveRecord\scalar()}: returns the value of the first column in the first row of the query result.
  • {@see \Yiisoft\ActiveRecord\column()}: returns the value of the first column in the query result.
  • {@see \Yiisoft\ActiveRecord\exists()}: returns a value indicating whether the query result has data or not.

Because ActiveQuery extends from {@see \Yiisoft\Db\Query\Query}, one can use query methods, such as {@see \Yiisoft\ActiveRecord\where()}, {@see \Yiisoft\ActiveRecord\orderBy()} to customize the query options.

ActiveQuery also provides the following more query options:

  • {@see \Yiisoft\ActiveRecord\with()}: list of relations that this query should be performed with.
  • {@see \Yiisoft\ActiveRecord\joinWith()}: reuse a relation query definition to add a join to a query.
  • {@see \Yiisoft\ActiveRecord\indexBy()}: the name of the column by which the query result should be indexed.
  • {@see \Yiisoft\ActiveRecord\asArray()}: whether to return each record as an array.

These options can be configured using methods of the same name. For example:

$customerQuery = Customer::query();
$query = $customerQuery->with('orders')->asArray()->all();

Relational query

In relational context, ActiveQuery represents a relation between two Active Record classes.

Relational ActiveQuery instances are usually created by calling {@see \Yiisoft\ActiveRecord\ActiveRecord::hasOne()} and {@see \Yiisoft\ActiveRecord\ActiveRecord::hasMany()}. An Active Record class declares a relation by defining a getter method which calls one of the above methods and returns the created ActiveQuery object.

A relation is specified by {@see \Yiisoft\ActiveRecord\link()} which represents the association between columns of different tables; and the multiplicity of the relation is indicated by {@see \Yiisoft\ActiveRecord\multiple()}.

If a relation involves a junction table, it may be specified by {@see \Yiisoft\ActiveRecord\via()} or {@see \Yiisoft\ActiveRecord\viaTable()} method.

These methods may only be called in a relational context. The same is true for {@see \Yiisoft\ActiveRecord\inverseOf()}, which marks a relation as inverse of another relation and {@see \Yiisoft\ActiveRecord\onCondition()} which adds a condition that is to be added to relational query join condition.

Public Methods

Hide inherited methods

Method Description Defined By
__clone() Clones internal objects Yiisoft\ActiveRecord\ActiveQuery
__construct() Yiisoft\ActiveRecord\ActiveQuery
alias() Yiisoft\ActiveRecord\ActiveQuery
andOn() Yiisoft\ActiveRecord\ActiveQuery
asArray() Yiisoft\ActiveRecord\ActiveQuery
batch() Yiisoft\ActiveRecord\ActiveQuery
createCommand() Creates a db command that can be used to execute this query. Yiisoft\ActiveRecord\ActiveQuery
each() Yiisoft\ActiveRecord\ActiveQuery
findByPk() Yiisoft\ActiveRecord\ActiveQuery
getInverseOf() Yiisoft\ActiveRecord\ActiveQuery
getJoinsWith() Yiisoft\ActiveRecord\ActiveQuery
getLink() Yiisoft\ActiveRecord\ActiveQuery
getModel() Yiisoft\ActiveRecord\ActiveQuery
getOn() Yiisoft\ActiveRecord\ActiveQuery
getPrimaryModel() Yiisoft\ActiveRecord\ActiveQuery
getSql() Yiisoft\ActiveRecord\ActiveQuery
getTablesUsedInFrom() Yiisoft\ActiveRecord\ActiveQuery
getVia() Yiisoft\ActiveRecord\ActiveQuery
getWith() Yiisoft\ActiveRecord\ActiveQuery
innerJoinWith() Yiisoft\ActiveRecord\ActiveQuery
inverseOf() Yiisoft\ActiveRecord\ActiveQuery
isAsArray() Yiisoft\ActiveRecord\ActiveQuery
isMultiple() Yiisoft\ActiveRecord\ActiveQuery
joinWith() Yiisoft\ActiveRecord\ActiveQuery
link() Yiisoft\ActiveRecord\ActiveQuery
multiple() Yiisoft\ActiveRecord\ActiveQuery
on() Yiisoft\ActiveRecord\ActiveQuery
one() Yiisoft\ActiveRecord\ActiveQuery
orOn() Yiisoft\ActiveRecord\ActiveQuery
populate() Yiisoft\ActiveRecord\ActiveQuery
populateRelation() Yiisoft\ActiveRecord\ActiveQuery
prepare() Yiisoft\ActiveRecord\ActiveQuery
primaryModel() Yiisoft\ActiveRecord\ActiveQuery
relatedRecords() Yiisoft\ActiveRecord\ActiveQuery
resetJoinsWith() Yiisoft\ActiveRecord\ActiveQuery
resetVia() Yiisoft\ActiveRecord\ActiveQuery
resetWith() Yiisoft\ActiveRecord\ActiveQuery
sql() Yiisoft\ActiveRecord\ActiveQuery
via() Yiisoft\ActiveRecord\ActiveQuery
viaTable() Yiisoft\ActiveRecord\ActiveQuery
with() Yiisoft\ActiveRecord\ActiveQuery

Protected Methods

Hide inherited methods

Method Description Defined By
createModels() Converts found rows into model instances. Yiisoft\ActiveRecord\ActiveQuery
getPrimaryTableName() Yiisoft\ActiveRecord\ActiveQuery
index() Yiisoft\ActiveRecord\ActiveQuery
queryScalar() Queries a scalar value by setting {@see select()} first. Yiisoft\ActiveRecord\ActiveQuery

Method Details

Hide inherited methods

__clone() public method

Clones internal objects

public mixed __clone ( )

                public function __clone()
{
    /// Make a clone of "via" object so that the same query object can be reused multiple times.
    if (is_object($this->via)) {
        $this->via = clone $this->via;
    } elseif (is_array($this->via)) {
        $this->via = [$this->via[0], clone $this->via[1], $this->via[2]];
    }
}

            
__construct() public method

public mixed __construct ( Yiisoft\ActiveRecord\ActiveRecordInterface|string $modelClass )
$modelClass Yiisoft\ActiveRecord\ActiveRecordInterface|string

                final public function __construct(
    ActiveRecordInterface|string $modelClass,
) {
    $this->model = $modelClass instanceof ActiveRecordInterface
        ? $modelClass
        : new $modelClass();
    parent::__construct($this->model->db());
}

            
alias() public method

public Yiisoft\ActiveRecord\ActiveQuery alias ( string $alias )
$alias string

                public function alias(string $alias): static
{
    if (count($this->from) < 2) {
        [$tableName] = TableNameAndAliasResolver::resolve($this);
        $this->from = [$alias => $tableName];
    } else {
        $tableName = $this->getPrimaryTableName();
        foreach ($this->from as $key => $table) {
            if ($table === $tableName) {
                unset($this->from[$key]);
                $this->from[$alias] = $tableName;
            }
        }
    }
    return $this;
}

            
andOn() public method

public Yiisoft\ActiveRecord\ActiveQuery andOn ( array|\Yiisoft\Db\Expression\ExpressionInterface|string $condition, array $params = [] )
$condition array|\Yiisoft\Db\Expression\ExpressionInterface|string
$params array

                public function andOn(array|ExpressionInterface|string $condition, array $params = []): static
{
    $this->on = $this->on === null
        ? $condition
        : ['and', $this->on, $condition];
    $this->addParams($params);
    return $this;
}

            
asArray() public method

public Yiisoft\ActiveRecord\ActiveQuery asArray ( boolean|null $value true )
$value boolean|null

                public function asArray(?bool $value = true): static
{
    $this->asArray = $value;
    return $this;
}

            
batch() public method

public \Yiisoft\Db\Query\BatchQueryResultInterface batch ( integer $batchSize 100 )
$batchSize integer

                public function batch(int $batchSize = 100): BatchQueryResultInterface
{
    /**
     * @var Closure(non-empty-array<array>):non-empty-array<object> $callback
     */
    $callback = $this->index(...);
    return parent::batch($batchSize)->indexBy(null)->resultCallback($callback);
}

            
createCommand() public method

Creates a db command that can be used to execute this query.

public \Yiisoft\Db\Command\CommandInterface createCommand ( )
throws \Yiisoft\Db\Exception\Exception

                public function createCommand(): CommandInterface
{
    if ($this->sql === null) {
        [$sql, $params] = $this->db->getQueryBuilder()->build($this);
    } else {
        $sql = $this->sql;
        $params = $this->params;
    }
    return $this->db->createCommand($sql, $params);
}

            
createModels() protected method

Converts found rows into model instances.

protected Yiisoft\ActiveRecord\ActiveRecordInterface[]|array[] createModels ( array[] $rows )
$rows array[]

The rows to be converted.

return Yiisoft\ActiveRecord\ActiveRecordInterface[]|array[]

The model instances.

                protected function createModels(array $rows): array
{
    if ($this->asArray) {
        $model = $this->getModel();
        return array_map(
            static fn(array $row) => Typecaster::cast($row, $model),
            $rows,
        );
    }
    if ($this->resultCallback !== null) {
        $rows = ($this->resultCallback)($rows);
        if ($rows[0] instanceof ActiveRecordInterface) {
            /** @psalm-var non-empty-list<ActiveRecordInterface> */
            return $rows;
        }
    }
    /** @var non-empty-list<array<string, mixed>> $rows */
    return array_map(
        fn(array $row) => $this->getModel()->populateRecord($row),
        $rows,
    );
}

            
each() public method

public \Yiisoft\Db\Query\DataReaderInterface each ( )

                public function each(): DataReaderInterface
{
    /** @psalm-suppress InvalidArgument */
    return $this->createCommand()
        ->query()
        ->indexBy($this->indexBy)
        ->resultCallback($this->populateOne(...));
}

            
findByPk() public method

public array|Yiisoft\ActiveRecord\ActiveRecordInterface|null findByPk ( array|float|integer|string $values )
$values array|float|integer|string

                public function findByPk(array|float|int|string $values): array|ActiveRecordInterface|null
{
    $values = (array) $values;
    $model = $this->getModel();
    $primaryKey = $model->primaryKey();
    if (empty($primaryKey)) {
        throw new InvalidConfigException($model::class . ' must have a primary key.');
    }
    if (count($primaryKey) !== count($values)) {
        throw new InvalidArgumentException(
            'The primary key has ' . count($primaryKey) . ' columns, but ' . count($values) . ' values are passed.',
        );
    }
    if (!empty($this->getJoins()) || !empty($this->getJoinsWith())) {
        $tableName = $model->tableName();
        foreach ($primaryKey as &$pk) {
            $pk = "$tableName.$pk";
        }
    }
    return (clone $this)->andWhere(array_combine($primaryKey, $values))->one();
}

            
getInverseOf() public method

public string|null getInverseOf ( )

                public function getInverseOf(): ?string
{
    return $this->inverseOf;
}

            
getJoinsWith() public method

public array getJoinsWith ( )

                public function getJoinsWith(): array
{
    return $this->joinsWith;
}

            
getLink() public method

public array getLink ( )

getModel() public method

public Yiisoft\ActiveRecord\ActiveRecordInterface getModel ( )

                public function getModel(): ActiveRecordInterface
{
    return clone $this->model;
}

            
getOn() public method

public array|\Yiisoft\Db\Expression\ExpressionInterface|string|null getOn ( )

                public function getOn(): array|ExpressionInterface|string|null
{
    return $this->on;
}

            
getPrimaryModel() public method

public Yiisoft\ActiveRecord\ActiveRecordInterface|null getPrimaryModel ( )

                public function getPrimaryModel(): ?ActiveRecordInterface
{
    return $this->primaryModel;
}

            
getPrimaryTableName() protected method

protected string getPrimaryTableName ( )

                protected function getPrimaryTableName(): string
{
    return $this->getModel()->tableName();
}

            
getSql() public method

public string|null getSql ( )

                public function getSql(): ?string
{
    return $this->sql;
}

            
getTablesUsedInFrom() public method

public array getTablesUsedInFrom ( )

                public function getTablesUsedInFrom(): array
{
    if (empty($this->from)) {
        return $this->db->getQuoter()->cleanUpTableNames([$this->getPrimaryTableName()]);
    }
    return parent::getTablesUsedInFrom();
}

            
getVia() public method

public array|Yiisoft\ActiveRecord\ActiveQueryInterface|null getVia ( )

                public function getVia(): array|ActiveQueryInterface|null
{
    return $this->via;
}

            
getWith() public method

public array getWith ( )

                public function getWith(): array
{
    return $this->with;
}

            
index() protected method

protected array index ( array $rows )
$rows array

                protected function index(array $rows): array
{
    return ArArrayHelper::index($this->populate($rows), $this->indexBy);
}

            
innerJoinWith() public method

public Yiisoft\ActiveRecord\ActiveQuery innerJoinWith ( array|string $with, array|boolean $eagerLoading true )
$with array|string
$eagerLoading array|boolean

                public function innerJoinWith(array|string $with, array|bool $eagerLoading = true): static
{
    return $this->joinWith($with, $eagerLoading, 'INNER JOIN');
}

            
inverseOf() public method

public Yiisoft\ActiveRecord\ActiveQuery inverseOf ( string $relationName )
$relationName string

                public function inverseOf(string $relationName): static
{
    $this->inverseOf = $relationName;
    return $this;
}

            
isAsArray() public method

public boolean|null isAsArray ( )

                public function isAsArray(): ?bool
{
    return $this->asArray;
}

            
isMultiple() public method

public boolean isMultiple ( )

                public function isMultiple(): bool
{
    return $this->multiple;
}

            
joinWith() public method

public Yiisoft\ActiveRecord\ActiveQuery joinWith ( array|string $with, array|boolean $eagerLoading true, array|string $joinType 'LEFT JOIN' )
$with array|string
$eagerLoading array|boolean
$joinType array|string

                public function joinWith(
    array|string $with,
    array|bool $eagerLoading = true,
    array|string $joinType = 'LEFT JOIN',
): static {
    $relations = [];
    foreach ((array) $with as $name => $callback) {
        if (is_int($name)) {
            $name = $callback;
            $callback = null;
        }
        /** @var string $name */
        if (preg_match('/^(.*?)(?:\s+AS\s+|\s+)(\w+)$/i', $name, $matches)) {
            /** The relation is defined with an alias, adjust callback to apply alias */
            [, $relation, $alias] = $matches;
            $name = $relation;
            $callback = static function (ActiveQueryInterface $query) use ($callback, $alias): void {
                $query->alias($alias);
                if ($callback !== null) {
                    $callback($query);
                }
            };
        }
        if ($callback === null) {
            $relations[] = $name;
        } else {
            $relations[$name] = $callback;
        }
    }
    $this->joinsWith[] = new JoinWith($relations, $eagerLoading, $joinType);
    return $this;
}

            
link() public method

public Yiisoft\ActiveRecord\ActiveQuery link ( array $value )
$value array

multiple() public method

public Yiisoft\ActiveRecord\ActiveQuery multiple ( boolean $value )
$value boolean

                public function multiple(bool $value): static
{
    $this->multiple = $value;
    return $this;
}

            
on() public method

public Yiisoft\ActiveRecord\ActiveQuery on ( array|\Yiisoft\Db\Expression\ExpressionInterface|string $condition, array $params = [] )
$condition array|\Yiisoft\Db\Expression\ExpressionInterface|string
$params array

                public function on(array|ExpressionInterface|string $condition, array $params = []): static
{
    $this->on = $condition;
    $this->addParams($params);
    return $this;
}

            
one() public method

public array|Yiisoft\ActiveRecord\ActiveRecordInterface|null one ( )

                public function one(): array|ActiveRecordInterface|null
{
    if ($this->shouldEmulateExecution()) {
        return null;
    }
    $row = $this->createCommand()->queryOne();
    if ($row === null) {
        return null;
    }
    return $this->populateOne($row);
}

            
orOn() public method

public Yiisoft\ActiveRecord\ActiveQuery orOn ( array|\Yiisoft\Db\Expression\ExpressionInterface|string $condition, array $params = [] )
$condition array|\Yiisoft\Db\Expression\ExpressionInterface|string
$params array

                public function orOn(array|ExpressionInterface|string $condition, array $params = []): static
{
    $this->on = $this->on === null
        ? $condition
        : ['or', $this->on, $condition];
    $this->addParams($params);
    return $this;
}

            
populate() public method

public array populate ( array $rows )
$rows array

                public function populate(array $rows): array
{
    if (empty($rows)) {
        return [];
    }
    if (!empty($this->joins) && $this->indexBy === null) {
        $rows = $this->removeDuplicatedRows($rows);
    }
    $models = $this->createModels($rows);
    if (!empty($this->with)) {
        $this->findWith($this->with, $models);
    }
    $this->addInverseRelations($models);
    return $models;
}

            
populateRelation() public method

public array populateRelation ( string $name, array &$primaryModels )
$name string
$primaryModels array

                public function populateRelation(string $name, array &$primaryModels): array
{
    return RelationPopulator::populate($this, $name, $primaryModels);
}

            
prepare() public method

public \Yiisoft\Db\Query\QueryInterface prepare ( \Yiisoft\Db\QueryBuilder\QueryBuilderInterface $builder )
$builder \Yiisoft\Db\QueryBuilder\QueryBuilderInterface
throws \Yiisoft\Definitions\Exception\CircularReferenceException
throws \Yiisoft\Db\Exception\Exception
throws \Yiisoft\Db\Exception\InvalidConfigException
throws \Yiisoft\Definitions\Exception\NotInstantiableException
throws Throwable
throws \Yiisoft\Definitions\Exception\InvalidConfigException

                public function prepare(QueryBuilderInterface $builder): QueryInterface
{
    /**
     * NOTE: Because the same ActiveQuery may be used to build different SQL statements, one for count query, the
     * other for row data query, it is important to make sure the same ActiveQuery can be used to build SQL
     * statements many times.
     */
    if (!empty($this->joinsWith)) {
        JoinsWithBuilder::build($this);
        /**
         * Clean it up to avoid issue @link https://github.com/yiisoft/yii2/issues/2687
         */
        $this->joinsWith = [];
    }
    if (empty($this->getFrom())) {
        $this->from = [$this->getPrimaryTableName()];
    }
    if (empty($this->getSelect()) && !empty($this->getJoins())) {
        [, $alias] = TableNameAndAliasResolver::resolve($this);
        $this->select(["$alias.*"]);
    }
    if ($this->primaryModel === null) {
        $query = $this->createInstance();
    } else {
        $where = $this->getWhere();
        if ($this->via instanceof ActiveQueryInterface) {
            $viaModels = JunctionRowsFinder::find($this->via, [$this->primaryModel]);
            ModelRelationFilter::apply($this, $viaModels);
        } elseif (is_array($this->via)) {
            [$viaName, $viaQuery, $viaCallableUsed] = $this->via;
            if ($viaQuery->isMultiple()) {
                if ($viaCallableUsed) {
                    $viaModels = $viaQuery->all();
                } elseif ($this->primaryModel->isRelationPopulated($viaName)) {
                    /** @var ActiveRecordInterface[]|array[] $viaModels */
                    $viaModels = $this->primaryModel->relation($viaName);
                } else {
                    $viaModels = $viaQuery->all();
                    $this->primaryModel->populateRelation($viaName, $viaModels);
                }
            } else {
                if ($viaCallableUsed) {
                    $model = $viaQuery->one();
                } elseif ($this->primaryModel->isRelationPopulated($viaName)) {
                    $model = $this->primaryModel->relation($viaName);
                } else {
                    $model = $viaQuery->one();
                    $this->primaryModel->populateRelation($viaName, $model);
                }
                $viaModels = $model === null ? [] : [$model];
            }
            ModelRelationFilter::apply($this, $viaModels);
        } else {
            ModelRelationFilter::apply($this, [$this->primaryModel]);
        }
        $query = $this->createInstance();
        $this->setWhere($where);
    }
    if (!empty($this->on)) {
        $query->andWhere($this->on);
    }
    return $query;
}

            
primaryModel() public method

public Yiisoft\ActiveRecord\ActiveQuery primaryModel ( Yiisoft\ActiveRecord\ActiveRecordInterface|null $value )
$value Yiisoft\ActiveRecord\ActiveRecordInterface|null

                public function primaryModel(?ActiveRecordInterface $value): static
{
    $this->primaryModel = $value;
    return $this;
}

            
queryScalar() protected method

Queries a scalar value by setting {@see select()} first.

Restores the value of select to make this query reusable.

protected boolean|string|integer|float|null queryScalar ( \Yiisoft\Db\Expression\ExpressionInterface|string $selectExpression )
$selectExpression \Yiisoft\Db\Expression\ExpressionInterface|string

The expression to be selected.

throws \Yiisoft\Db\Exception\Exception
throws InvalidArgumentException
throws \Yiisoft\Db\Exception\InvalidConfigException
throws \Yiisoft\Db\Exception\NotSupportedException
throws Throwable

                protected function queryScalar(string|ExpressionInterface $selectExpression): bool|string|int|float|null
{
    if ($this->sql === null) {
        return parent::queryScalar($selectExpression);
    }
    $command = (new Query($this->db))->select([$selectExpression])
        ->from(['c' => "($this->sql)"])
        ->params($this->params)
        ->createCommand();
    return $command->queryScalar();
}

            
relatedRecords() public method

public Yiisoft\ActiveRecord\ActiveRecordInterface|array|null relatedRecords ( )

                public function relatedRecords(): ActiveRecordInterface|array|null
{
    return $this->multiple ? $this->all() : $this->one();
}

            
resetJoinsWith() public method

public void resetJoinsWith ( )

                public function resetJoinsWith(): void
{
    $this->joinsWith = [];
}

            
resetVia() public method

public Yiisoft\ActiveRecord\ActiveQuery resetVia ( )

                public function resetVia(): static
{
    $this->via = null;
    return $this;
}

            
resetWith() public method

public Yiisoft\ActiveRecord\ActiveQuery resetWith ( )

                public function resetWith(): static
{
    $this->with = [];
    $this->joinsWith = array_map(
        static fn(JoinWith $joinWith) => $joinWith->withoutEagerLoading(),
        $this->joinsWith,
    );
    return $this;
}

            
sql() public method

public Yiisoft\ActiveRecord\ActiveQuery sql ( string|null $value )
$value string|null

                public function sql(?string $value): static
{
    $this->sql = $value;
    return $this;
}

            
via() public method

public Yiisoft\ActiveRecord\ActiveQuery via ( string $relationName, callable|null $callable null )
$relationName string
$callable callable|null

                public function via(string $relationName, ?callable $callable = null): static
{
    if ($this->primaryModel === null) {
        throw new InvalidConfigException('Setting via is only supported for relational queries.');
    }
    $relation = $this->primaryModel->relationQuery($relationName);
    $callableUsed = $callable !== null;
    $this->via = [$relationName, $relation, $callableUsed];
    if ($callableUsed) {
        $callable($relation);
    }
    return $this;
}

            
viaTable() public method

public Yiisoft\ActiveRecord\ActiveQuery viaTable ( string $tableName, array $link, callable|null $callable null )
$tableName string
$link array
$callable callable|null

                public function viaTable(string $tableName, array $link, ?callable $callable = null): static
{
    $model = $this->primaryModel ?? $this->model;
    $relation = (new static($model))
        ->from([$tableName])
        ->link($link)
        ->multiple(true)
        ->asArray();
    $this->via = $relation;
    if ($callable !== null) {
        $callable($relation);
    }
    return $this;
}

            
with() public method

public Yiisoft\ActiveRecord\ActiveQuery with ( array|string $with )
$with array|string

                public function with(array|string ...$with): static
{
    if (isset($with[0]) && is_array($with[0])) {
        /// the parameter is given as an array
        $with = $with[0];
    }
    if (empty($this->with)) {
        $this->with = $with;
    } elseif (!empty($with)) {
        foreach ($with as $name => $value) {
            if (is_int($name)) {
                // repeating relation is fine as `normalizeRelations()` handle it well
                $this->with[] = $value;
            } else {
                $this->with[$name] = $value;
            }
        }
    }
    return $this;
}