Browse Source

more docs about joinwith()

tags/2.0.0-beta
Qiang Xue 11 years ago
parent
commit
dc720d9bf4
  1. 45
      docs/guide/active-record.md
  2. 10
      framework/yii/db/ActiveQuery.php

45
docs/guide/active-record.md

@ -400,14 +400,53 @@ $orders = Order::find()->joinWith('books')->all();
// find all orders that contain books, and sort the orders by the book names. // find all orders that contain books, and sort the orders by the book names.
$orders = Order::find()->joinWith([ $orders = Order::find()->joinWith([
'books' => function ($query) { 'books' => function ($query) {
$query->orderBy('tbl_item.name'); $query->orderBy('tbl_item.id');
} }
])->all(); ])->all();
``` ```
Note that [[ActiveQuery::joinWith()]] differs from [[ActiveQuery::with()]] in that the former will build up Note that [[ActiveQuery::joinWith()]] differs from [[ActiveQuery::with()]] in that the former will build up
and execute a JOIN SQL statement. For example, `Order::find()->joinWith('books')->all()` returns all orders that and execute a JOIN SQL statement for the primary model class. For example, `Order::find()->joinWith('books')->all()`
contain books, while `Order::find()->with('books')->all()` returns all orders regardless they contain books or not. returns all orders that contain books, while `Order::find()->with('books')->all()` returns all orders
regardless they contain books or not.
Because `joinWith()` will cause generating a JOIN SQL statement, you are responsible to disambiguate column
names. For example, we use `tbl_item.id` to disambiguate the `id` column reference because both of the order table
and the item table contain a column named `id`.
You may join with one or multiple relations. You may also join with sub-relations. For example,
```php
// join with multiple relations
// find out the orders that contain books and are placed by customers who registered within the past 24 hours
$orders = Order::find()->joinWith([
'books',
'customer' => function ($query) {
$query->where('tbl_customer.create_time > ' . (time() - 24 * 3600));
}
])->all();
// join with sub-relations: join with books and books' authors
$orders = Order::find()->joinWith('books.author')->all();
```
By default, when you join with a relation, the relation will also be eagerly loaded. You may change this behavior
by passing the `$eagerLoading` parameter which specifies whether to eager load the specified relations.
Also, when the relations are joined with the primary table, the default join type is `INNER JOIN`. You may change
to use other type of joins, such as `LEFT JOIN`.
Below are some more examples,
```php
// find all orders that contain books, but do not eager loading "books".
$orders = Order::find()->joinWith('books', false)->all();
// find all orders and sort them by the customer IDs. Do not eager loading "customer".
$orders = Order::find()->joinWith([
'customer' => function ($query) {
$query->orderBy('tbl_customer.id');
},
], false, 'LEFT JOIN')->all();
```
Working with Relationships Working with Relationships

10
framework/yii/db/ActiveQuery.php

@ -220,9 +220,13 @@ class ActiveQuery extends Query implements ActiveQueryInterface
* ])->all(); * ])->all();
* ``` * ```
* *
* @param bool $eagerLoading * @param boolean|array $eagerLoading whether to eager load the relations specified in `$with`.
* @param string $joinType * When this is a boolean, it applies to all relations specified in `$with`. Use an array
* @return $this * to explicitly list which relations in `$with` need to be eagerly loaded.
* @param string|array $joinType the join type of the relations specified in `$with`.
* When this is a string, it applies to all relations specified in `$with`. Use an array
* in the format of `relationName => joinType` to specify different join types for different relations.
* @return static the query object itself
*/ */
public function joinWith($with, $eagerLoading = true, $joinType = 'INNER JOIN') public function joinWith($with, $eagerLoading = true, $joinType = 'INNER JOIN')
{ {

Loading…
Cancel
Save