Commit 323937f2 by Carsten Brandt

Merge pull request #3061 from yiisoft/grid-view-relations

add guide about filtering and sorting related columns
parents 3cdf95d5 b1f4d5d4
...@@ -274,15 +274,56 @@ echo GridView::widget([ ...@@ -274,15 +274,56 @@ echo GridView::widget([
Working with model relations Working with model relations
---------------------------- ----------------------------
When displaying Active records in a GridView you might encounter the case where you display values of related When displaying active records in a GridView you might encounter the case where you display values of related
columns such as the posts authors name instead of just his `id`. columns such as the posts authors name instead of just his `id`.
You do this by defining the attribute name in columns as `author.name` when the `Post` model You do this by defining the attribute name in columns as `author.name` when the `Post` model
has a relation named `author` and the author model has an attribute `name`. has a relation named `author` and the author model has an attribute `name`.
The GridView will then display the name of the author but sorting and filtering are not enabled by default. The GridView will then display the name of the author but sorting and filtering are not enabled by default.
You have to adjust the `PostSearch` model to add this functionallity. You have to adjust the `PostSearch` model that has been introduced in the last section to add this functionallity.
TBD To enable sorting on a related column you have to join the related table and add the sorting rule
to the Sort component of the dataprovider:
```php
$query = Post::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
// join with relation `author` that is a relation to the table `users`
// and set the table alias to be `author`
$query->joinWith(['author' => function($query) { $query->from(['author' => 'users']); }]);
// enable sorting for the related column
$dataProvider->sort->attributes['author.name'] = [
'asc' => ['author.name' => SORT_ASC],
'desc' => ['author.name' => SORT_DESC],
];
// ...
```
Filtering also needs the joinWith call as above. You also need to define the searchable column in attributes and rules like this:
```php
public function attributes()
{
// add related fields to searchable attributes when in search scenario
if ($this->getScenario() == 'search') {
return array_merge(parent::attributes(), ['site.number']);
}
return parent::attributes();
}
public function rules()
{
return [
[['id'], 'integer'],
[['title', 'creation_date', 'author.name'], 'safe'],
];
}
```
- https://github.com/yiisoft/yii2/issues/1581 In `search()` you then just add another filter condition with `$query->andFilterWhere(['LIKE', 'author.name', $this->getAttribute('author.name')]);`.
- https://github.com/yiisoft/yii2/issues/3013
> Info: For more information on `joinWith` and the queries performed in the background, check the
> [active record docs on eager and lazy loading](active-record.md#lazy-and-eager-loading).
...@@ -1732,7 +1732,7 @@ class BaseHtml ...@@ -1732,7 +1732,7 @@ class BaseHtml
*/ */
public static function getAttributeName($attribute) public static function getAttributeName($attribute)
{ {
if (preg_match('/(^|.*\])(\w+)(\[.*|$)/', $attribute, $matches)) { if (preg_match('/(^|.*\])([\w\.]+)(\[.*|$)/', $attribute, $matches)) {
return $matches[2]; return $matches[2];
} else { } else {
throw new InvalidParamException('Attribute name must contain word characters only.'); throw new InvalidParamException('Attribute name must contain word characters only.');
...@@ -1755,7 +1755,7 @@ class BaseHtml ...@@ -1755,7 +1755,7 @@ class BaseHtml
*/ */
public static function getAttributeValue($model, $attribute) public static function getAttributeValue($model, $attribute)
{ {
if (!preg_match('/(^|.*\])(\w+)(\[.*|$)/', $attribute, $matches)) { if (!preg_match('/(^|.*\])([\w\.]+)(\[.*|$)/', $attribute, $matches)) {
throw new InvalidParamException('Attribute name must contain word characters only.'); throw new InvalidParamException('Attribute name must contain word characters only.');
} }
$attribute = $matches[2]; $attribute = $matches[2];
...@@ -1805,7 +1805,7 @@ class BaseHtml ...@@ -1805,7 +1805,7 @@ class BaseHtml
public static function getInputName($model, $attribute) public static function getInputName($model, $attribute)
{ {
$formName = $model->formName(); $formName = $model->formName();
if (!preg_match('/(^|.*\])(\w+)(\[.*|$)/', $attribute, $matches)) { if (!preg_match('/(^|.*\])([\w\.]+)(\[.*|$)/', $attribute, $matches)) {
throw new InvalidParamException('Attribute name must contain word characters only.'); throw new InvalidParamException('Attribute name must contain word characters only.');
} }
$prefix = $matches[1]; $prefix = $matches[1];
......
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