Docs about 'selecting extra fields' with Active Record added

This commit is contained in:
Klimov Paul
2015-04-23 12:44:43 +03:00
parent f2f211f610
commit 13b10bdb9a

View File

@ -1336,3 +1336,72 @@ $customers = Customer::find()->with([
> Info: In Yii 1.1, there is a concept called *scope*. Scope is no longer directly supported in Yii 2.0,
and you should use customized query classes and query methods to achieve the same goal.
## Selecting extra fields
When Active Record instance is populated from query results, its attributes are filled up by corresponding column
values from received data set.
You are able to fetch additional columns or values from query and store it inside the Active Record.
For example, assume we have a table named 'room', which contains information about rooms available in the hotel.
Each room stores information about its geometrical size using fields 'length', 'width', 'height'.
Imagine we need to retrieve list of all available rooms with their volume in descendant order.
So you can not calculate volume using PHP, because we need to sort the records by its value, but you also want 'volume'
to be displayed in the list.
To achieve the goal, you need to declare an extra field in your 'Room' Active Record class, which will store 'volume' value:
```php
class Room extends \yii\db\ActiveRecord
{
public $volume;
// ...
}
```
Then you need to compose a query, which calculates volume of the room and performs the sort:
```php
$rooms = Room::find()
->select([
'{{room}}.*', // select all columns
'([[length]] * [[width]].* [[height]]) AS volume', // calculate a volume
])
->orderBy('volume DESC') // apply sort
->all();
foreach ($rooms as $room) {
echo $room->volume; // contains value calculated by SQL
}
```
Ability to select extra fields can be exceptionally useful for aggregation queries.
Assume you need to display a list of customers with the count of orders they have made.
First of all, you need to declare a `Customer` class with 'orders' relation and extra field for count storage:
```php
class Customer extends \yii\db\ActiveRecord
{
public $ordersCount;
// ...
public function getOrders()
{
return $this->hasMany(Order::className(), ['customer_id' => 'id']);
}
}
```
Then you can compose a query, which joins the orders and calculates their count:
```php
$customers = Customer::find()
->select([
'{{customer}}.*', // select all customer fields
'COUNT({{order}}.id) AS ordersCount' // calculate orders count
])
->joinWith('orders') // ensure table junction
->groupBy('{{customer}}.id') // group the result to ensure aggregation function works
->all();
```