Commit 646f233f by Alexander Makarov

Merge pull request #6183 from cdvrooman/patch-25

[skip ci] Update db-active-record.md
parents 9b9dfefa 32302395
...@@ -489,7 +489,7 @@ Sometimes, two tables are related together via an intermediary table called a [j ...@@ -489,7 +489,7 @@ Sometimes, two tables are related together via an intermediary table called a [j
we can customize the [[yii\db\ActiveQuery]] object by calling its [[yii\db\ActiveQuery::via()|via()]] or we can customize the [[yii\db\ActiveQuery]] object by calling its [[yii\db\ActiveQuery::via()|via()]] or
[[yii\db\ActiveQuery::viaTable()|viaTable()]] method. [[yii\db\ActiveQuery::viaTable()|viaTable()]] method.
For example, if table `order` and table `item` are related via junction table `order_item`, For example, if table `order` and table `item` are related via the junction table `order_item`,
we can declare the `items` relation in the `Order` class like the following: we can declare the `items` relation in the `Order` class like the following:
```php ```php
...@@ -529,7 +529,7 @@ class Order extends \yii\db\ActiveRecord ...@@ -529,7 +529,7 @@ class Order extends \yii\db\ActiveRecord
Lazy and Eager Loading Lazy and Eager Loading
---------------------- ----------------------
As described earlier, when you access the related objects the first time, ActiveRecord will perform a DB query As described earlier, when you access the related objects for the first time, ActiveRecord will perform a DB query
to retrieve the corresponding data and populate it into the related objects. No query will be performed to retrieve the corresponding data and populate it into the related objects. No query will be performed
if you access the same related objects again. We call this *lazy loading*. For example, if you access the same related objects again. We call this *lazy loading*. For example,
...@@ -721,7 +721,7 @@ and you may also join with sub-relations. For example, ...@@ -721,7 +721,7 @@ and you may also join with sub-relations. For example,
```php ```php
// join with multiple relations // join with multiple relations
// find out the orders that contain books and are placed by customers who registered within the past 24 hours // find the orders that contain books and were placed by customers who registered within the past 24 hours
$orders = Order::find()->innerJoinWith([ $orders = Order::find()->innerJoinWith([
'books', 'books',
'customer' => function ($query) { 'customer' => function ($query) {
...@@ -732,7 +732,7 @@ $orders = Order::find()->innerJoinWith([ ...@@ -732,7 +732,7 @@ $orders = Order::find()->innerJoinWith([
$orders = Order::find()->joinWith('books.author')->all(); $orders = Order::find()->joinWith('books.author')->all();
``` ```
Behind the scene, Yii will first execute a JOIN SQL statement to bring back the primary models Behind the scenes, Yii will first execute a JOIN SQL statement to bring back the primary models
satisfying the conditions applied to the JOIN SQL. It will then execute a query for each relation satisfying the conditions applied to the JOIN SQL. It will then execute a query for each relation
and populate the corresponding related records. and populate the corresponding related records.
...@@ -759,7 +759,7 @@ you may use [[yii\db\ActiveQuery::innerJoinWith()|innerJoinWith()]]. ...@@ -759,7 +759,7 @@ you may use [[yii\db\ActiveQuery::innerJoinWith()|innerJoinWith()]].
Below are some more examples, Below are some more examples,
```php ```php
// find all orders that contain books, but do not eager loading "books". // find all orders that contain books, but do not eager load "books".
$orders = Order::find()->innerJoinWith('books', false)->all(); $orders = Order::find()->innerJoinWith('books', false)->all();
// which is equivalent to the above // which is equivalent to the above
$orders = Order::find()->joinWith('books', false, 'INNER JOIN')->all(); $orders = Order::find()->joinWith('books', false, 'INNER JOIN')->all();
...@@ -782,7 +782,7 @@ In the above, the [[yii\db\ActiveRecord::hasMany()|hasMany()]] method returns an ...@@ -782,7 +782,7 @@ In the above, the [[yii\db\ActiveRecord::hasMany()|hasMany()]] method returns an
upon which [[yii\db\ActiveQuery::onCondition()|onCondition()]] is called upon which [[yii\db\ActiveQuery::onCondition()|onCondition()]] is called
to specify that only items whose `category_id` is 1 should be returned. to specify that only items whose `category_id` is 1 should be returned.
When you perform query using [[yii\db\ActiveQuery::joinWith()|joinWith()]], the on-condition will be put in the ON part When you perform a query using [[yii\db\ActiveQuery::joinWith()|joinWith()]], the ON condition will be put in the ON part
of the corresponding JOIN query. For example, of the corresponding JOIN query. For example,
```php ```php
...@@ -822,14 +822,13 @@ $customer->link('orders', $order); ...@@ -822,14 +822,13 @@ $customer->link('orders', $order);
``` ```
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
class Post extends \yii\db\ActiveRecord class Post extends \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.
See also See also
-------- --------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment