The [[yii\db\ActiveRecord::link()|link()]] call above will set the `customer_id` of the order to be the primary key
The [[yii\db\ActiveRecord::link()|link()]] call above will set the `customer_id` of the order to be the primary key
value of `$customer` and then call [[yii\db\ActiveRecord::save()|save()]] to save the order into database.
value of `$customer` and then call [[yii\db\ActiveRecord::save()|save()]] to save the order into the database.
Cross-DBMS Relations
Cross-DBMS Relations
--------------------
--------------------
ActiveRecord allows to establish relationship between entities from different DBMS. For example: between relational
ActiveRecord allows you to establish relationships between entities from different DBMS. For example: between a relational database table and MongoDB collection. Such a relation does not require any special code:
database table and MongoDB collection. Such relation does not require any special code:
```php
```php
// Relational database Active Record
// Relational database Active Record
...
@@ -880,10 +879,9 @@ You may call additional query methods, such as [[yii\db\ActiveQuery::where()|whe
...
@@ -880,10 +879,9 @@ You may call additional query methods, such as [[yii\db\ActiveQuery::where()|whe
to further specify the query conditions.
to further specify the query conditions.
It is possible that you may want to call the same set of query methods in different places. If this is the case,
It is possible that you may want to call the same set of query methods in different places. If this is the case,
you should consider defining the so-called *scopes*. A scope is essentially a method defined in a custom query class that
you should consider defining the so-called *scopes*. A scope is essentially a method defined in a custom query class that calls a set of query methods to modify the query object. You can then use a scope instead of calling a normal query method.
calls a set of query methods to modify the query object. You can then use a scope like calling a normal query method.
Two steps are required to define a scope. First create a custom query class for your model and define the needed scope
Two steps are required to define a scope. First, create a custom query class for your model and define the needed scope
methods in this class. For example, create a `CommentQuery` class for the `Comment` model and define the `active()`
methods in this class. For example, create a `CommentQuery` class for the `Comment` model and define the `active()`
scope method like the following:
scope method like the following:
...
@@ -949,7 +947,7 @@ class Post extends \yii\db\ActiveRecord
...
@@ -949,7 +947,7 @@ class Post extends \yii\db\ActiveRecord
}
}
```
```
Or use the scopes on-the-fly when performing relational query:
Or use the scopes on-the-fly when performing a relational query:
```php
```php
$posts=Post::find()->with([
$posts=Post::find()->with([
...
@@ -980,8 +978,8 @@ Transactional operations
...
@@ -980,8 +978,8 @@ Transactional operations
---------------------
---------------------
There are two ways of dealing with transactions while working with Active Record. First way is doing everything manually
There are two ways of dealing with transactions while working with Active Record. First way is doing everything manually
as described in "transactions" section of "[Database basics](db-dao.md)". Another way is to do it by implementing
as described in the "transactions" section of "[Database basics](db-dao.md)". Another way is to implement the
`transactions` method where you can specify which operations are to be wrapped into transaction per model scenario:
`transactions` method where you can specify which operations are to be wrapped into transactions on a per model scenario:
```php
```php
classPostextends\yii\db\ActiveRecord
classPostextends\yii\db\ActiveRecord
...
@@ -998,8 +996,8 @@ class Post extends \yii\db\ActiveRecord
...
@@ -998,8 +996,8 @@ class Post extends \yii\db\ActiveRecord
}
}
```
```
In the above `admin` and `api` are model scenarios and constants starting with `OP_` are operations that should
In the above `admin` and `api` are model scenarios and the constants starting with `OP_` are operations that should
be wrapped in transaction for these scenarios. Supported operations are `OP_INSERT`, `OP_UPDATE` and `OP_DELETE`.
be wrapped in transactions for these scenarios. Supported operations are `OP_INSERT`, `OP_UPDATE` and `OP_DELETE`.
`OP_ALL` stands for all three.
`OP_ALL` stands for all three.
Such automatic transactions are especially useful if you're doing additional database changes in `beforeSave`,
Such automatic transactions are especially useful if you're doing additional database changes in `beforeSave`,
...
@@ -1009,7 +1007,7 @@ Optimistic Locks
...
@@ -1009,7 +1007,7 @@ Optimistic Locks
--------------
--------------
Optimistic locking allows multiple users to access the same record for edits and avoids
Optimistic locking allows multiple users to access the same record for edits and avoids
potential conflicts. In case when a user attempts to save the record upon some staled data
potential conflicts. For example, when a user attempts to save the record upon some staled data
(because another user has modified the data), a [[\yii\db\StaleObjectException]] exception will be thrown,
(because another user has modified the data), a [[\yii\db\StaleObjectException]] exception will be thrown,
and the update or deletion is skipped.
and the update or deletion is skipped.
...
@@ -1018,7 +1016,7 @@ Optimistic locking is only supported by `update()` and `delete()` methods and is
...
@@ -1018,7 +1016,7 @@ Optimistic locking is only supported by `update()` and `delete()` methods and is
To use Optimistic locking:
To use Optimistic locking:
1. Create a column to store the version number of each row. The column type should be `BIGINT DEFAULT 0`.
1. Create a column to store the version number of each row. The column type should be `BIGINT DEFAULT 0`.
Override `optimisticLock()` method to return the name of this column.
Override the `optimisticLock()` method to return the name of this column.
2. In the Web form that collects the user input, add a hidden field that stores
2. In the Web form that collects the user input, add a hidden field that stores
the lock version of the recording being updated.
the lock version of the recording being updated.
3. In the controller action that does the data updating, try to catch the [[\yii\db\StaleObjectException]]
3. In the controller action that does the data updating, try to catch the [[\yii\db\StaleObjectException]]
...
@@ -1028,9 +1026,7 @@ To use Optimistic locking:
...
@@ -1028,9 +1026,7 @@ To use Optimistic locking:
Dirty Attributes
Dirty Attributes
--------------
--------------
An attribute is considered dirty if its value was modified since model was loaded from database or since most recent
An attribute is considered dirty if its value was modified after the model was loaded from database or since the most recent data save. When saving record data by calling `save()`, `update()`, `insert()` etc. only dirty attributes are saved into the database. If there are no dirty attributes then there is nothing to be saved so no query will be issued at all.
data save. When saving record data by calling `save()`, `update()`, `insert()` etc. only dirty attributes are saved
into database. If there are no dirty attributes there's nothing to be saved so no query will be issued at all.