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([
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`.
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`.
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
- https://github.com/yiisoft/yii2/issues/3013
In `search()` you then just add another filter condition with `$query->andFilterWhere(['LIKE', 'author.name', $this->getAttribute('author.name')]);`.
> 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
*/
public static function getAttributeName($attribute)
{
if (preg_match('/(^|.*\])(\w+)(\[.*|$)/', $attribute, $matches)) {
if (preg_match('/(^|.*\])([\w\.]+)(\[.*|$)/', $attribute, $matches)) {
return $matches[2];
} else {
throw new InvalidParamException('Attribute name must contain word characters only.');
......@@ -1755,7 +1755,7 @@ class BaseHtml
*/
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.');
}
$attribute = $matches[2];
......@@ -1805,7 +1805,7 @@ class BaseHtml
public static function getInputName($model, $attribute)
{
$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.');
}
$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