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 Yiisoft\ActiveRecord\Trait\RepositoryTrait::findOne(), Yiisoft\ActiveRecord\Trait\RepositoryTrait::findBySql(), Yiisoft\ActiveRecord\Trait\RepositoryTrait::findAll().

Relational queries are created by Yiisoft\ActiveRecord\ActiveRecordInterface::hasOne() and Yiisoft\ActiveRecord\ActiveRecordInterface::hasMany().

Normal Query

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

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

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

ActiveQuery also provides the following more query options:

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 Yiisoft\ActiveRecord\ActiveRecordInterface::hasOne() and Yiisoft\ActiveRecord\ActiveRecordInterface::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 Yiisoft\ActiveRecord\ActiveQuery::link() which represents the association between columns of different tables; and the multiplicity of the relation is indicated by Yiisoft\ActiveRecord\ActiveQuery::multiple().

If a relation involves a junction table, it may be specified by Yiisoft\ActiveRecord\ActiveQuery::via() or Yiisoft\ActiveRecord\ActiveQuery::viaTable() method.

These methods may only be called in a relational context. The same is true for Yiisoft\ActiveRecord\ActiveQuery::inverseOf(), which marks a relation as inverse of another relation and Yiisoft\ActiveRecord\ActiveQuery::on() 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 Query::select() first. Yiisoft\ActiveRecord\ActiveQuery

Method Details

Hide inherited methods

__clone() public method

Clones internal objects

public __clone( ): mixed

                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 __construct( Yiisoft\ActiveRecord\ActiveRecordInterface|string $modelClass ): mixed
$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 alias( string $alias ): Yiisoft\ActiveRecord\ActiveQuery
$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 andOn( array|\Yiisoft\Db\Expression\ExpressionInterface|string $condition, array $params = [] ): Yiisoft\ActiveRecord\ActiveQuery
$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 asArray( boolean|null $value true ): Yiisoft\ActiveRecord\ActiveQuery
$value boolean|null

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

            
batch() public method

public batch( integer $batchSize 100 ): \Yiisoft\Db\Query\BatchQueryResultInterface
$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 createCommand( ): \Yiisoft\Db\Command\CommandInterface
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 createModels( array[] $rows ): Yiisoft\ActiveRecord\ActiveRecordInterface[]|array[]
$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 each( ): \Yiisoft\Db\Query\DataReaderInterface

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

            
findByPk() public method

public findByPk( array|float|integer|string $values ): array|Yiisoft\ActiveRecord\ActiveRecordInterface|null
$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 getInverseOf( ): string|null

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

            
getJoinsWith() public method

public getJoinsWith( ): array

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

            
getLink() public method

public getLink( ): array

getModel() public method

public getModel( ): Yiisoft\ActiveRecord\ActiveRecordInterface

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

            
getOn() public method

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

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

            
getPrimaryModel() public method

public getPrimaryModel( ): Yiisoft\ActiveRecord\ActiveRecordInterface|null

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

            
getPrimaryTableName() protected method

protected getPrimaryTableName( ): string

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

            
getSql() public method

public getSql( ): string|null

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

            
getTablesUsedInFrom() public method

public getTablesUsedInFrom( ): array

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

            
getVia() public method

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

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

            
getWith() public method

public getWith( ): array

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

            
index() protected method

protected index( array $rows ): array
$rows array

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

            
innerJoinWith() public method

public innerJoinWith( array|string $with, array|boolean $eagerLoading true ): Yiisoft\ActiveRecord\ActiveQuery
$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 inverseOf( string $relationName ): Yiisoft\ActiveRecord\ActiveQuery
$relationName string

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

            
isAsArray() public method

public isAsArray( ): boolean|null

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

            
isMultiple() public method

public isMultiple( ): boolean

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

            
joinWith() public method

public joinWith( array|string $with, array|boolean $eagerLoading true, array|string $joinType 'LEFT JOIN' ): Yiisoft\ActiveRecord\ActiveQuery
$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 link( array $value ): Yiisoft\ActiveRecord\ActiveQuery
$value array

multiple() public method

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

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

            
on() public method

public on( array|\Yiisoft\Db\Expression\ExpressionInterface|string $condition, array $params = [] ): Yiisoft\ActiveRecord\ActiveQuery
$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 one( ): array|Yiisoft\ActiveRecord\ActiveRecordInterface|null

                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 orOn( array|\Yiisoft\Db\Expression\ExpressionInterface|string $condition, array $params = [] ): Yiisoft\ActiveRecord\ActiveQuery
$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 populate( array $rows ): array
$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 populateRelation( string $name, array &$primaryModels ): array
$name string
$primaryModels array

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

            
prepare() public method

public prepare( \Yiisoft\Db\QueryBuilder\QueryBuilderInterface $builder ): \Yiisoft\Db\Query\QueryInterface
$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 primaryModel( Yiisoft\ActiveRecord\ActiveRecordInterface|null $value ): Yiisoft\ActiveRecord\ActiveQuery
$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 Query::select() first.

Restores the value of select to make this query reusable.

protected queryScalar( \Yiisoft\Db\Expression\ExpressionInterface|string $selectExpression ): boolean|string|integer|float|null
$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 relatedRecords( ): Yiisoft\ActiveRecord\ActiveRecordInterface|array|null

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

            
resetJoinsWith() public method

public resetJoinsWith( ): void

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

            
resetVia() public method

public resetVia( ): Yiisoft\ActiveRecord\ActiveQuery

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

            
resetWith() public method

public resetWith( ): Yiisoft\ActiveRecord\ActiveQuery

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

            
sql() public method

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

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

            
via() public method

public via( string $relationName, callable|null $callable null ): Yiisoft\ActiveRecord\ActiveQuery
$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 viaTable( string $tableName, array $link, callable|null $callable null ): Yiisoft\ActiveRecord\ActiveQuery
$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 with( array|string $with ): Yiisoft\ActiveRecord\ActiveQuery
$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;
}