0 follower

Class Yiisoft\ActiveRecord\ActiveRecord

InheritanceYiisoft\ActiveRecord\ActiveRecord » Yiisoft\ActiveRecord\AbstractActiveRecord
ImplementsYiisoft\ActiveRecord\ActiveRecordInterface

Active Record class which implements {@see ActiveRecordInterface} interface with the minimum set of methods.

Active Record implements the Active Record design pattern.

The premise behind Active Record is that an individual {@see \Yiisoft\ActiveRecord\ActiveRecord} object is associated with a specific row in a database table. The object's properties are mapped to the columns of the corresponding table.

Referencing an Active Record property is equivalent to accessing the corresponding table column for that record.

As an example, say that the Customer ActiveRecord class is associated with the customer table.

This would mean that the class's name property is automatically mapped to the name column in customer table. Thanks to Active Record, assuming the variable $customer is an object of type Customer, to get the value of the name column for the table row, you can use the expression $customer->name.

In this example, Active Record is providing an object-oriented interface for accessing data stored in the database. But Active Record provides much more functionality than this.

To declare an ActiveRecord class, you need to extend {@see \Yiisoft\ActiveRecord\ActiveRecord} and implement the tableName method:

class Customer extends ActiveRecord
{
    public static function tableName(): string
    {
        return 'customer';
    }
}

The tableName method only has to return the name of the database table associated with the class.

Class instances are obtained in one of two ways:

Using the new operator to create a new, empty object. Using a method to fetch an existing record (or records) from the database.

Below is an example showing some typical usage of ActiveRecord:

$user = new User();
$user->name = 'Qiang';
$user->save(); // a new row is inserted into user table

// the following will retrieve the user 'CeBe' from the database
$user = User::query()->where(['name' => 'CeBe'])->one();

// this will get related records from orders table when relation is defined
$orders = $user->orders;

For more details and usage information on ActiveRecord, {@see \Yiisoft\ActiveRecord\the guide article on ActiveRecord}

Public Methods

Hide inherited methods

Method Description Defined By
assignOldValue() Yiisoft\ActiveRecord\AbstractActiveRecord
assignOldValues() Yiisoft\ActiveRecord\AbstractActiveRecord
column() Yiisoft\ActiveRecord\ActiveRecord
createQuery() Yiisoft\ActiveRecord\AbstractActiveRecord
db() Yiisoft\ActiveRecord\AbstractActiveRecord
delete() Yiisoft\ActiveRecord\AbstractActiveRecord
deleteAll() Yiisoft\ActiveRecord\AbstractActiveRecord
equals() Yiisoft\ActiveRecord\AbstractActiveRecord
get() Yiisoft\ActiveRecord\AbstractActiveRecord
hasMany() Yiisoft\ActiveRecord\AbstractActiveRecord
hasOne() Yiisoft\ActiveRecord\AbstractActiveRecord
hasProperty() Yiisoft\ActiveRecord\AbstractActiveRecord
insert() Yiisoft\ActiveRecord\AbstractActiveRecord
isChanged() Yiisoft\ActiveRecord\AbstractActiveRecord
isNew() Yiisoft\ActiveRecord\AbstractActiveRecord
isPrimaryKey() Yiisoft\ActiveRecord\AbstractActiveRecord
isPropertyChanged() Yiisoft\ActiveRecord\AbstractActiveRecord
isPropertyChangedNonStrict() Yiisoft\ActiveRecord\AbstractActiveRecord
isRelationPopulated() Yiisoft\ActiveRecord\AbstractActiveRecord
link() Yiisoft\ActiveRecord\AbstractActiveRecord
loadDefaultValues() Yiisoft\ActiveRecord\ActiveRecord
markAsExisting() Yiisoft\ActiveRecord\AbstractActiveRecord
markAsNew() Yiisoft\ActiveRecord\AbstractActiveRecord
markPropertyChanged() Yiisoft\ActiveRecord\AbstractActiveRecord
newValues() Yiisoft\ActiveRecord\AbstractActiveRecord
oldValue() Yiisoft\ActiveRecord\AbstractActiveRecord
oldValues() Yiisoft\ActiveRecord\AbstractActiveRecord
populateProperties() Yiisoft\ActiveRecord\AbstractActiveRecord
populateRecord() Yiisoft\ActiveRecord\ActiveRecord
populateRelation() Yiisoft\ActiveRecord\AbstractActiveRecord
primaryKey() Yiisoft\ActiveRecord\ActiveRecord
primaryKeyOldValue() Yiisoft\ActiveRecord\AbstractActiveRecord
primaryKeyOldValues() Yiisoft\ActiveRecord\AbstractActiveRecord
primaryKeyValue() Yiisoft\ActiveRecord\AbstractActiveRecord
primaryKeyValues() Yiisoft\ActiveRecord\AbstractActiveRecord
propertyNames() Yiisoft\ActiveRecord\ActiveRecord
propertyValues() Yiisoft\ActiveRecord\AbstractActiveRecord
query() Yiisoft\ActiveRecord\AbstractActiveRecord
refresh() Repopulates this active record with the latest data. Yiisoft\ActiveRecord\AbstractActiveRecord
relatedRecords() Yiisoft\ActiveRecord\AbstractActiveRecord
relation() Yiisoft\ActiveRecord\AbstractActiveRecord
relationQuery() Yiisoft\ActiveRecord\AbstractActiveRecord
resetRelation() Yiisoft\ActiveRecord\AbstractActiveRecord
save() Yiisoft\ActiveRecord\AbstractActiveRecord
set() Yiisoft\ActiveRecord\AbstractActiveRecord
tableName() Yiisoft\ActiveRecord\AbstractActiveRecord
tableSchema() Yiisoft\ActiveRecord\ActiveRecord
unlink() Yiisoft\ActiveRecord\AbstractActiveRecord
unlinkAll() Yiisoft\ActiveRecord\AbstractActiveRecord
update() Yiisoft\ActiveRecord\AbstractActiveRecord
updateAll() Yiisoft\ActiveRecord\AbstractActiveRecord
updateAllCounters() Yiisoft\ActiveRecord\AbstractActiveRecord
updateCounters() Yiisoft\ActiveRecord\AbstractActiveRecord
upsert() Yiisoft\ActiveRecord\AbstractActiveRecord

Method Details

Hide inherited methods

assignOldValue() public method
public void assignOldValue ( string $propertyName, mixed $value )
$propertyName string
$value mixed

                public function assignOldValue(string $propertyName, mixed $value): void
{
    if (isset($this->oldValues[$propertyName]) || $this->hasProperty($propertyName)) {
        $this->oldValues[$propertyName] = $value;
    } else {
        throw new InvalidArgumentException(static::class . ' has no property named "' . $propertyName . '".');
    }
}

            
assignOldValues() public method
public void assignOldValues ( array|null $propertyValues null )
$propertyValues array|null

                public function assignOldValues(?array $propertyValues = null): void
{
    $this->oldValues = $propertyValues;
}

            
column() public method

public \Yiisoft\Db\Schema\Column\ColumnInterface column ( string $propertyName )
$propertyName string

                public function column(string $propertyName): ColumnInterface
{
    return $this->tableSchema()->getColumn($propertyName)
        ?? $this->db()->getColumnFactory()->fromType(ColumnType::STRING, ['name' => $propertyName]);
}

            
createQuery() public method
public Yiisoft\ActiveRecord\ActiveQueryInterface createQuery ( Yiisoft\ActiveRecord\ActiveRecordInterface|string|null $modelClass null )
$modelClass Yiisoft\ActiveRecord\ActiveRecordInterface|string|null

                public function createQuery(ActiveRecordInterface|string|null $modelClass = null): ActiveQueryInterface
{
    return static::query($modelClass ?? $this);
}

            
createRelationQuery() protected method

Defined in: Yiisoft\ActiveRecord\AbstractActiveRecord::createRelationQuery()

Creates a query instance for has-one or has-many relation.

protected Yiisoft\ActiveRecord\ActiveQueryInterface createRelationQuery ( Yiisoft\ActiveRecord\ActiveRecordInterface|string $modelClass, array $link, boolean $multiple )
$modelClass Yiisoft\ActiveRecord\ActiveRecordInterface|string

The class name of the related record.

$link array

The primary-foreign key constraint.

$multiple boolean

Whether this query represents a relation to more than one record.

return Yiisoft\ActiveRecord\ActiveQueryInterface

The relational query object.

                protected function createRelationQuery(
    ActiveRecordInterface|string $modelClass,
    array $link,
    bool $multiple,
): ActiveQueryInterface {
    return $this->createQuery($modelClass)->primaryModel($this)->link($link)->multiple($multiple);
}

            
db() public method
public \Yiisoft\Db\Connection\ConnectionInterface db ( )

                public function db(): ConnectionInterface
{
    return ConnectionProvider::get();
}

            
delete() public method
public integer delete ( )

                public function delete(): int
{
    return $this->deleteInternal();
}

            
deleteAll() public method
public integer deleteAll ( array $condition = [], array $params = [] )
$condition array
$params array

                public function deleteAll(array $condition = [], array $params = []): int
{
    $command = $this->db()->createCommand();
    $command->delete($this->tableName(), $condition, $params);
    return $command->execute();
}

            
deleteInternal() protected method
protected integer deleteInternal ( )
return integer

The number of rows deleted.

throws \Yiisoft\Db\Exception\Exception
throws Throwable

                protected function deleteInternal(): int
{
    /**
     * We don't check the return value of deleteAll() because it is possible the record is already deleted in
     * the database and thus the method will return 0
     */
    $condition = $this->primaryKeyOldValues();
    if ($this instanceof OptimisticLockInterface) {
        $lock = $this->optimisticLockPropertyName();
        $condition[$lock] = $this->get($lock);
        $result = $this->deleteAll($condition);
        if ($result === 0) {
            throw new OptimisticLockException(
                'The object being deleted is outdated.',
            );
        }
    } else {
        $result = $this->deleteAll($condition);
    }
    $this->assignOldValues();
    return $result;
}

            
equals() public method
public boolean equals ( Yiisoft\ActiveRecord\ActiveRecordInterface $record )
$record Yiisoft\ActiveRecord\ActiveRecordInterface

                public function equals(ActiveRecordInterface $record): bool
{
    if ($this->isNew() || $record->isNew()) {
        return false;
    }
    return $this->tableName() === $record->tableName() && $this->primaryKeyValues() === $record->primaryKeyValues();
}

            
get() public method
public mixed get ( string $propertyName )
$propertyName string

                public function get(string $propertyName): mixed
{
    return $this->propertyValuesInternal()[$propertyName] ?? null;
}

            
hasDependentRelations() protected method
protected boolean hasDependentRelations ( string $propertyName )
$propertyName string

                protected function hasDependentRelations(string $propertyName): bool
{
    return isset($this->relationsDependencies[$propertyName]);
}

            
hasMany() public method
public Yiisoft\ActiveRecord\ActiveQueryInterface hasMany ( Yiisoft\ActiveRecord\ActiveRecordInterface|string $modelClass, array $link )
$modelClass Yiisoft\ActiveRecord\ActiveRecordInterface|string
$link array

                public function hasMany(ActiveRecordInterface|string $modelClass, array $link): ActiveQueryInterface
{
    return $this->createRelationQuery($modelClass, $link, true);
}

            
hasOne() public method
public Yiisoft\ActiveRecord\ActiveQueryInterface hasOne ( Yiisoft\ActiveRecord\ActiveRecordInterface|string $modelClass, array $link )
$modelClass Yiisoft\ActiveRecord\ActiveRecordInterface|string
$link array

                public function hasOne(ActiveRecordInterface|string $modelClass, array $link): ActiveQueryInterface
{
    return $this->createRelationQuery($modelClass, $link, false);
}

            
hasProperty() public method
public boolean hasProperty ( string $name )
$name string

                public function hasProperty(string $name): bool
{
    return in_array($name, $this->propertyNames(), true);
}

            
insert() public method
public void insert ( array|null $properties null )
$properties array|null

                public function insert(?array $properties = null): void
{
    $this->insertInternal($properties);
}

            
insertInternal() protected method

protected void insertInternal ( array|null $properties null )
$properties array|null

                protected function insertInternal(?array $properties = null): void
{
    if (!$this->isNew()) {
        throw new InvalidCallException('The record is not new and cannot be inserted.');
    }
    $values = $this->newPropertyValues($properties);
    $primaryKeys = $this->db()->createCommand()->insertReturningPks($this->tableName(), $values);
    $this->populateRawValues($primaryKeys, $values);
}

            
isChanged() public method
public boolean isChanged ( )

                public function isChanged(): bool
{
    return !empty($this->newValues());
}

            
isNew() public method
public boolean isNew ( )

                public function isNew(): bool
{
    return $this->oldValues === null;
}

            
isPrimaryKey() public method
public boolean isPrimaryKey ( array $keys )
$keys array

                public function isPrimaryKey(array $keys): bool
{
    $pks = $this->primaryKey();
    return count($keys) === count($pks)
        && count(array_intersect($keys, $pks)) === count($pks);
}

            
isPropertyChanged() public method
public boolean isPropertyChanged ( string $name )
$name string

                public function isPropertyChanged(string $name): bool
{
    $values = $this->propertyValuesInternal();
    if (empty($this->oldValues) || !array_key_exists($name, $this->oldValues)) {
        return array_key_exists($name, $values);
    }
    return !array_key_exists($name, $values) || $values[$name] !== $this->oldValues[$name];
}

            
isPropertyChangedNonStrict() public method
public boolean isPropertyChangedNonStrict ( string $name )
$name string

                public function isPropertyChangedNonStrict(string $name): bool
{
    $values = $this->propertyValuesInternal();
    if (empty($this->oldValues) || !array_key_exists($name, $this->oldValues)) {
        return array_key_exists($name, $values);
    }
    return !array_key_exists($name, $values) || $values[$name] != $this->oldValues[$name];
}

            
isRelationPopulated() public method
public boolean isRelationPopulated ( string $name )
$name string

                public function isRelationPopulated(string $name): bool
{
    return array_key_exists($name, $this->related);
}

            
link() public method
public void link ( string $relationName, Yiisoft\ActiveRecord\ActiveRecordInterface $linkModel, array $extraColumns = [] )
$relationName string
$linkModel Yiisoft\ActiveRecord\ActiveRecordInterface
$extraColumns array

loadDefaultValues() public method

public Yiisoft\ActiveRecord\ActiveRecord loadDefaultValues ( boolean $skipIfSet true )
$skipIfSet boolean

                public function loadDefaultValues(bool $skipIfSet = true): static
{
    foreach ($this->tableSchema()->getColumns() as $name => $column) {
        if ($column->getDefaultValue() !== null && (!$skipIfSet || $this->get($name) === null)) {
            $this->set($name, $column->getDefaultValue());
        }
    }
    return $this;
}

            
markAsExisting() public method
public void markAsExisting ( )

                public function markAsExisting(): void
{
    $this->oldValues = $this->propertyValuesInternal();
}

            
markAsNew() public method
public void markAsNew ( )

                public function markAsNew(): void
{
    $this->oldValues = null;
}

            
markPropertyChanged() public method
public void markPropertyChanged ( string $name )
$name string

                public function markPropertyChanged(string $name): void
{
    if ($this->oldValues !== null && $name !== '') {
        unset($this->oldValues[$name]);
    }
}

            
newPropertyValues() protected method

Defined in: Yiisoft\ActiveRecord\AbstractActiveRecord::newPropertyValues()

Returns the property values that have been modified.

You may specify the properties to be returned as list of name or name-value pairs. If name-value pair specified, the corresponding property values will be modified.

Only the {@see \Yiisoft\ActiveRecord\newValues() changed property values} will be returned.

protected array newPropertyValues ( array|null $properties null )
$properties array|null

List of property names or name-values pairs that need to be returned. Defaults to null, meaning all changed property values will be returned.

return array

The changed property values (name-value pairs).

                protected function newPropertyValues(?array $properties = null): array
{
    if (empty($properties) || array_is_list($properties)) {
        return $this->newValues($properties);
    }
    $names = [];
    foreach ($properties as $name => $value) {
        if (is_int($name)) {
            $names[] = $value;
        } else {
            $this->set($name, $value);
            $names[] = $name;
        }
    }
    return $this->newValues($names);
}

            
newValues() public method
public array newValues ( array|null $propertyNames null )
$propertyNames array|null

                public function newValues(?array $propertyNames = null): array
{
    $values = $this->propertyValues($propertyNames);
    if ($this->oldValues === null) {
        return $values;
    }
    $result = array_diff_key($values, $this->oldValues);
    foreach (array_diff_key($values, $result) as $name => $value) {
        if ($value !== $this->oldValues[$name]) {
            $result[$name] = $value;
        }
    }
    return $result;
}

            
oldValue() public method
public mixed oldValue ( string $propertyName )
$propertyName string

                public function oldValue(string $propertyName): mixed
{
    return $this->oldValues[$propertyName] ?? null;
}

            
oldValues() public method
public array oldValues ( )

                public function oldValues(): array
{
    return $this->oldValues ?? [];
}

            
populateProperties() public method
public void populateProperties ( array $values )
$values array

                public function populateProperties(array $values): void
{
    $values = array_intersect_key($values, array_flip($this->propertyNames()));
    foreach ($values as $name => $value) {
        $this->populateProperty($name, $value);
    }
}

            
populateProperty() protected method

protected void populateProperty ( string $name, mixed $value )
$name string
$value mixed

                protected function populateProperty(string $name, mixed $value): void
{
    $this->$name = $value;
}

            
populateRecord() public method

public Yiisoft\ActiveRecord\ActiveRecord populateRecord ( array|object $row )
$row array|object

                public function populateRecord(array|object $row): static
{
    $row = ArArrayHelper::toArray($row);
    $row = Typecaster::cast($row, $this);
    /** @var $this */
    return parent::populateRecord($row);
}

            
populateRelation() public method
public void populateRelation ( string $name, array|Yiisoft\ActiveRecord\ActiveRecordInterface|null $records )
$name string
$records array|Yiisoft\ActiveRecord\ActiveRecordInterface|null

                public function populateRelation(string $name, array|ActiveRecordInterface|null $records): void
{
    foreach ($this->relationsDependencies as &$relationNames) {
        unset($relationNames[$name]);
    }
    $this->related[$name] = $records;
}

            
primaryKey() public method

public array primaryKey ( )

                public function primaryKey(): array
{
    return $this->tableSchema()->getPrimaryKey();
}

            
primaryKeyOldValue() public method
public float|integer|string|null primaryKeyOldValue ( )

                public function primaryKeyOldValue(): float|int|string|null
{
    $keys = $this->primaryKey();
    /**
     * @var float|int|string|null We assume primary key old value always is float, int, string or null.
     */
    return match (count($keys)) {
        1 => $this->oldValues[$keys[0]] ?? null,
        0 => throw new LogicException(
            static::class . ' does not have a primary key. You should either define a primary key for '
            . $this->tableName() . ' table or override the primaryKey() method.',
        ),
        default => throw new LogicException(
            static::class . ' has multiple primary keys. Use primaryKeyOldValues() method instead.',
        ),
    };
}

            
primaryKeyOldValues() public method
public array primaryKeyOldValues ( )

                public function primaryKeyOldValues(): array
{
    $keys = $this->primaryKey();
    if (empty($keys)) {
        throw new LogicException(
            static::class . ' does not have a primary key. You should either define a primary key for '
            . $this->tableName() . ' table or override the primaryKey() method.',
        );
    }
    $values = [];
    foreach ($keys as $name) {
        /**
         * @var bool|float|int|string|null We assume primary key old values always are scalar or null.
         */
        $values[$name] = $this->oldValues[$name] ?? null;
    }
    return $values;
}

            
primaryKeyValue() public method
public float|integer|string|null primaryKeyValue ( )

                public function primaryKeyValue(): float|int|string|null
{
    $keys = $this->primaryKey();
    /**
     * @var float|int|string|null We assume primary key value always is float, int, string or null.
     */
    return match (count($keys)) {
        1 => $this->get($keys[0]),
        0 => throw new LogicException(
            static::class . ' does not have a primary key. You should either define a primary key for '
            . $this->tableName() . ' table or override the primaryKey() method.',
        ),
        default => throw new LogicException(
            static::class . ' has multiple primary keys. Use primaryKeyValues() method instead.',
        ),
    };
}

            
primaryKeyValues() public method
public array primaryKeyValues ( )

                public function primaryKeyValues(): array
{
    $keys = $this->primaryKey();
    if (empty($keys)) {
        throw new LogicException(
            static::class . ' does not have a primary key. You should either define a primary key for '
            . $this->tableName() . ' table or override the primaryKey() method.',
        );
    }
    $values = [];
    foreach ($keys as $name) {
        /**
         * @var bool|float|int|string|null We assume primary key old values always are scalar or null.
         */
        $values[$name] = $this->get($name);
    }
    return $values;
}

            
propertyNames() public method

public array propertyNames ( )

                public function propertyNames(): array
{
    return $this->tableSchema()->getColumnNames();
}

            
propertyValues() public method
public array propertyValues ( array|null $names null, array $except = [] )
$names array|null
$except array

                public function propertyValues(?array $names = null, array $except = []): array
{
    $names ??= $this->propertyNames();
    if (!empty($except)) {
        $names = array_diff($names, $except);
    }
    return array_intersect_key($this->propertyValuesInternal(), array_flip($names));
}

            
propertyValuesInternal() protected method

protected array propertyValuesInternal ( )

                protected function propertyValuesInternal(): array
{
    return get_object_vars($this);
}

            
query() public static method
public static Yiisoft\ActiveRecord\ActiveQueryInterface query ( Yiisoft\ActiveRecord\ActiveRecordInterface|string|null $modelClass null )
$modelClass Yiisoft\ActiveRecord\ActiveRecordInterface|string|null

                public static function query(ActiveRecordInterface|string|null $modelClass = null): ActiveQueryInterface
{
    return new ActiveQuery($modelClass ?? static::class);
}

            
refresh() public method

Defined in: Yiisoft\ActiveRecord\AbstractActiveRecord::refresh()

Repopulates this active record with the latest data.

public boolean refresh ( )
return boolean

Whether the row still exists in the database. If true, the latest data will be populated to this active record. Otherwise, this record will remain unchanged.

                public function refresh(): bool
{
    $record = $this->createQuery()->findByPk($this->primaryKeyOldValues());
    return $this->refreshInternal($record);
}

            
refreshInternal() protected method

Defined in: Yiisoft\ActiveRecord\AbstractActiveRecord::refreshInternal()

Repopulates this active record with the latest data from a newly fetched instance.

protected boolean refreshInternal ( Yiisoft\ActiveRecord\ActiveRecordInterface|array|null $record null )
$record Yiisoft\ActiveRecord\ActiveRecordInterface|array|null

The record to take property values from.

return boolean

Whether refresh was successful.

{@see \Yiisoft\ActiveRecord\refresh()}

                protected function refreshInternal(array|ActiveRecordInterface|null $record = null): bool
{
    if ($record === null || is_array($record)) {
        return false;
    }
    foreach ($this->propertyNames() as $name) {
        $this->populateProperty($name, $record->get($name));
    }
    $this->oldValues = $record->oldValues();
    $this->related = [];
    $this->relationsDependencies = [];
    return true;
}

            
relatedRecords() public method
public array relatedRecords ( )

                public function relatedRecords(): array
{
    return $this->related;
}

            
relation() public method
public Yiisoft\ActiveRecord\ActiveRecordInterface|array|null relation ( string $name )
$name string

                public function relation(string $name): ActiveRecordInterface|array|null
{
    if (array_key_exists($name, $this->related)) {
        return $this->related[$name];
    }
    return $this->retrieveRelation($name);
}

            
relationQuery() public method
public Yiisoft\ActiveRecord\ActiveQueryInterface relationQuery ( string $name )
$name string

                public function relationQuery(string $name): ActiveQueryInterface
{
    throw new InvalidArgumentException(static::class . ' has no relation named "' . $name . '".');
}

            
resetDependentRelations() protected method

Defined in: Yiisoft\ActiveRecord\AbstractActiveRecord::resetDependentRelations()

Resets dependent related models checking if their links contain specific property.

protected void resetDependentRelations ( string $propertyName )
$propertyName string

The changed property name.

                protected function resetDependentRelations(string $propertyName): void
{
    foreach ($this->relationsDependencies[$propertyName] as $relation) {
        unset($this->related[$relation]);
    }
    unset($this->relationsDependencies[$propertyName]);
}

            
resetRelation() public method
public void resetRelation ( string $name )
$name string

                public function resetRelation(string $name): void
{
    foreach ($this->relationsDependencies as &$relationNames) {
        unset($relationNames[$name]);
    }
    unset($this->related[$name]);
}

            
retrieveRelation() protected method
protected Yiisoft\ActiveRecord\ActiveRecordInterface|array|null retrieveRelation ( string $name )
$name string

                protected function retrieveRelation(string $name): ActiveRecordInterface|array|null
{
    /** @var ActiveQueryInterface $query */
    $query = $this->relationQuery($name);
    $this->setRelationDependencies($name, $query);
    return $this->related[$name] = $query->relatedRecords();
}

            
save() public method
public void save ( array|null $properties null )
$properties array|null

                public function save(?array $properties = null): void
{
    if ($this->isNew()) {
        $this->insert($properties);
        return;
    }
    $this->update($properties);
}

            
set() public method
public void set ( string $propertyName, mixed $value )
$propertyName string
$value mixed

                public function set(string $propertyName, mixed $value): void
{
    if (
        isset($this->relationsDependencies[$propertyName])
        && ($value === null || $this->get($propertyName) !== $value)
    ) {
        $this->resetDependentRelations($propertyName);
    }
    $this->populateProperty($propertyName, $value);
}

            
tableName() public method
public string tableName ( )

                public function tableName(): string
{
    $name = (new ReflectionClass($this))->getShortName();
    /** @var string $name */
    $name = preg_replace('/[A-Z]([A-Z](?![a-z]))*/', '_$0', $name);
    $name = strtolower(ltrim($name, '_'));
    return '{{%' . $name . '}}';
}

            
tableSchema() public method

public \Yiisoft\Db\Schema\TableSchemaInterface tableSchema ( )

                public function tableSchema(): TableSchemaInterface
{
    $tableSchema = $this->db()->getSchema()->getTableSchema($this->tableName());
    if ($tableSchema === null) {
        throw new InvalidConfigException('The table does not exist: ' . $this->tableName());
    }
    return $tableSchema;
}

            
unlink() public method
public void unlink ( string $relationName, Yiisoft\ActiveRecord\ActiveRecordInterface $linkedModel, boolean $delete false )
$relationName string
$linkedModel Yiisoft\ActiveRecord\ActiveRecordInterface
$delete boolean

unlinkAll() public method
public void unlinkAll ( string $relationName, boolean $delete false )
$relationName string
$delete boolean

                public function unlinkAll(string $relationName, bool $delete = false): void
{
    $viaModel = null;
    $viaTable = null;
    $relation = $this->relationQuery($relationName);
    $viaRelation = $relation->getVia();
    if ($viaRelation !== null) {
        if (is_array($viaRelation)) {
            [$viaName, $viaRelation] = $viaRelation;
            $viaModel = $viaRelation->getModel();
            unset($this->related[$viaName]);
        } else {
            $from = $viaRelation->getFrom();
            $viaTable = reset($from);
        }
        $condition = [];
        $nulls = [];
        if ($viaRelation instanceof ActiveQueryInterface) {
            foreach ($viaRelation->getLink() as $a => $b) {
                $nulls[$a] = null;
                $condition[$a] = $this->get($b);
            }
            if (!empty($viaRelation->getWhere())) {
                $condition = ['and', $condition, $viaRelation->getWhere()];
            }
            if (!empty($viaRelation->getOn())) {
                $condition = ['and', $condition, $viaRelation->getOn()];
            }
        }
        if ($viaModel !== null) {
            if ($delete) {
                $viaModel->deleteAll($condition);
            } else {
                $viaModel->updateAll($nulls, $condition);
            }
        } elseif (is_string($viaTable)) {
            $command = $this->db()->createCommand();
            if ($delete) {
                $command->delete($viaTable, $condition)->execute();
            } else {
                $command->update($viaTable, $nulls, $condition)->execute();
            }
        }
    } else {
        $relatedModel = $relation->getModel();
        $link = $relation->getLink();
        if (!$delete && count($link) === 1 && is_array($this->get($b = reset($link)))) {
            /** relation via array valued property */
            $this->set($b, []);
            $this->save();
        } else {
            $nulls = [];
            $condition = [];
            foreach ($relation->getLink() as $a => $b) {
                $nulls[$a] = null;
                $condition[$a] = $this->get($b);
            }
            if (!empty($relation->getWhere())) {
                $condition = ['and', $condition, $relation->getWhere()];
            }
            if (!empty($relation->getOn())) {
                $condition = ['and', $condition, $relation->getOn()];
            }
            if ($delete) {
                $relatedModel->deleteAll($condition);
            } else {
                $relatedModel->updateAll($nulls, $condition);
            }
        }
    }
    unset($this->related[$relationName]);
}

            
update() public method
public integer update ( array|null $properties null )
$properties array|null

                public function update(?array $properties = null): int
{
    return $this->updateInternal($properties);
}

            
updateAll() public method
public integer updateAll ( array $propertyValues, array|string $condition = [], array|\Yiisoft\Db\Expression\ExpressionInterface|string|null $from null, array $params = [] )
$propertyValues array
$condition array|string
$from array|\Yiisoft\Db\Expression\ExpressionInterface|string|null
$params array

                public function updateAll(array $propertyValues, array|string $condition = [], array|ExpressionInterface|string|null $from = null, array $params = []): int
{
    $command = $this->db()->createCommand();
    $command->update($this->tableName(), $propertyValues, $condition, $from, $params);
    return $command->execute();
}

            
updateAllCounters() public method
public integer updateAllCounters ( array $counters, array|string $condition '', array|\Yiisoft\Db\Expression\ExpressionInterface|string|null $from null, array $params = [] )
$counters array
$condition array|string
$from array|\Yiisoft\Db\Expression\ExpressionInterface|string|null
$params array

                public function updateAllCounters(
    array $counters,
    array|string $condition = '',
    array|ExpressionInterface|string|null $from = null,
    array $params = [],
): int {
    $n = 0;
    foreach ($counters as $name => $value) {
        $counters[$name] = new Expression("[[$name]]+:bp$n", [":bp$n" => $value]);
        $n++;
    }
    return $this->db()
        ->createCommand()
        ->update($this->tableName(), $counters, $condition, $from, $params)
        ->execute();
}

            
updateCounters() public method
public void updateCounters ( array $counters )
$counters array

                public function updateCounters(array $counters): void
{
    if ($this->isNew()) {
        throw new LogicException('Updating counters is not possible for new records.');
    }
    $this->updateAllCounters($counters, $this->primaryKeyOldValues());
    foreach ($counters as $name => $value) {
        /**
         * @psalm-suppress MixedOperand We assume that the counter value is always an integer.
         */
        $value += $this->get($name) ?? 0;
        $this->populateProperty($name, $value);
        $this->oldValues[$name] = $value;
    }
}

            
updateInternal() protected method
protected integer updateInternal ( array|null $properties null )
$properties array|null

Property names or name-values pairs to update, null means all properties.

return integer

The number of rows affected.

throws \Yiisoft\Db\Exception\Exception
throws \Yiisoft\Db\Exception\NotSupportedException

                protected function updateInternal(?array $properties = null): int
{
    if ($this->isNew()) {
        throw new InvalidCallException('The record is new and cannot be updated.');
    }
    $values = $this->newPropertyValues($properties);
    if (empty($values)) {
        return 0;
    }
    $condition = $this->primaryKeyOldValues();
    if ($this instanceof OptimisticLockInterface) {
        $lock = $this->optimisticLockPropertyName();
        /**
         * @var int $lockValue We assume that optimistic lock property value is always an integer.
         */
        $lockValue = $this->get($lock);
        $condition[$lock] = $lockValue;
        $values[$lock] = ++$lockValue;
        $rows = $this->updateAll($values, $condition);
        if ($rows === 0) {
            throw new OptimisticLockException(
                'The object being updated is outdated.',
            );
        }
        $this->populateProperty($lock, $lockValue);
    } else {
        $rows = $this->updateAll($values, $condition);
    }
    $this->oldValues = array_merge($this->oldValues ?? [], $values);
    return $rows;
}

            
upsert() public method
public void upsert ( array|null $insertProperties null, array|boolean $updateProperties true )
$insertProperties array|null
$updateProperties array|boolean

                public function upsert(?array $insertProperties = null, array|bool $updateProperties = true): void
{
    $this->upsertInternal($insertProperties, $updateProperties);
}

            
upsertInternal() protected method

protected void upsertInternal ( array|null $insertProperties null, array|boolean $updateProperties true )
$insertProperties array|null
$updateProperties array|boolean

                protected function upsertInternal(?array $insertProperties = null, array|bool $updateProperties = true): void
{
    if (!$this->isNew()) {
        throw new InvalidCallException('The record is not new and cannot be inserted.');
    }
    $insertValues = $this->newPropertyValues($insertProperties);
    $returnProperties = $insertProperties !== null
        ? array_merge($this->primaryKey(), array_keys($insertValues))
        : null;
    if (is_array($updateProperties)) {
        /**
         * @var string[] $updateNames Values of `$updateProperties` parameter which are integer keys
         * represent property names
         */
        $updateNames = array_filter($updateProperties, is_int(...), ARRAY_FILTER_USE_KEY);
        if (!empty($updateNames)) {
            $updateProperties = array_merge(
                array_diff_key($updateProperties, $updateNames),
                $this->newPropertyValues($updateNames),
            );
        }
        /** @psalm-var array<string, mixed> $updateProperties */
        if ($returnProperties !== null) {
            $returnProperties = array_merge($returnProperties, array_keys($updateProperties));
        }
    }
    $returnedValues = $this->db()->createCommand()
        ->upsertReturning($this->tableName(), $insertValues, $updateProperties, $returnProperties);
    $this->populateRawValues($returnedValues);
}