Я собираюсь использовать первую форму нормализации в моем проекте Yii2, поэтому я добавил таблицу, подобную этой
| id | post_id | tag_id |
и когда я нахожусь в моделях сообщений, я надел это:
public function getTags() { return $this->hasMany(PostTags::className(), ['post_id' => 'id']); }
В виду виджета я добавил 'tags.tag_id', но он не показывает никаких данных.
Есть ли способ показать эти теги в виджетах DetailView и GridView ?
Может быть, я могу написать «group_concat» где-нибудь?
Я бы рекомендовал написать виджет для отображения списка ссылок связанных записей. Он многоразовый, предотвращает генерацию HTML в модели / контроллере, уменьшает количество кода в поле зрения.
<?php namespace common\widgets; use yii\base\Widget; use yii\helpers\Html; /** * Widget for display list of links to related models */ class RelatedList extends Widget { /** * @var \yii\db\ActiveRecord[] Related models */ public $models = []; /** * @var string Base to build text content of the link. * You should specify attribute name. In case of dynamic generation ('getFullName()') you should specify just 'fullName'. */ public $linkContentBase = 'name'; /** * @var string Route to build url to related model */ public $viewRoute; /** * @inheritdoc */ public function run() { if (!$this->models) { return null; } $items = []; foreach ($this->models as $model) { $items[] = Html::a($model->{$this->linkContentBase}, [$this->viewRoute, 'id' => $model->id]); } return Html::ul($items, [ 'class' => 'list-unstyled', 'encode' => false, ]); } }
Вот несколько примеров (предполагая, что имя тега хранится в столбце name
).
Использование в GridView
:
[ 'attribute' => 'tags', 'format' => 'raw', 'value' => function ($model) { /* @var $model common\models\Post */ return RelatedList::widget([ 'models' => $model->tags, 'viewRoute' => '/tags/view', ]); }, ],
Использование в DetailView
:
/* @var $model common\models\Post */ ... [ 'attribute' => 'tags', 'format' => 'raw', 'value' => RelatedList::widget([ 'models' => $model->tags, 'viewRoute' => '/tags/view', ]), ],
Не забудьте установить формат raw
, потому что по умолчанию контент отображается как обычный текст, чтобы предотвратить атаки XSS (html специальные символы экранируются).
Вы можете изменить это в соответствии с вашими потребностями, это просто пример.