Программирование, веб-кодинг

Организация тегов у блога через связанную таблицу

Создание связей моделей, промежуточная таблица для связи блога и тегов

Организация тегов у блога через связанную таблицу

Отличный вебинар Дмитрия Елисеева про связи моделей - http://www.elisdn.ru/blog/89/related-models-on-yii...

По части тегов:

В виде admin.php имеем GridView

<?= GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => [
            ...
            'title',
            [
                'attribute'=>'status',
                'filter'=>[0=>'Нет', 1=>'Да'],
                'format'=>'boolean',
            ],
            [
                'label'=>'Tags',
                'attribute'=>'tag_id',
                'filter'=>Tag::find()->select(['name', 'id'])->indexBy('id')->column(),
                'value'=> function (Blog $blog) {
                    return implode(', ', ArrayHelper::map($blog->tagss, 'id', 'name'));
                },
            ],
            ...

            ['class' => 'yii\grid\ActionColumn'],
        ],
    ]); ?>

В модели Blog пишем связи

public function getBlogTags()
    {
        return $this->hasMany(BlogTag::className(), ['blog_id' => 'id']);
    }
    
    public function getTagss()
    {
        return $this->hasMany(Tag::className(), ['id' => 'tag_id'])->viaTable('blog_tag_assn', ['blog_id' => 'id']);
    }

В модели Tag пишем связи

public function getBlogTags()
    {
        return $this->hasMany(BlogTag::className(), ['tag_id' => 'id']);
    }
    /**
     * @return \yii\db\ActiveQuery
     */
    public function getBlogs()
    {
        return $this->hasMany(Blog::className(), ['id' => 'blog_id'])->viaTable('{{%blog_tag_assn}}', ['tag_id' => 'id']);
    }

В модели BlogTag промежуточной таблицы пишем связи

public function getTag()
    {
        return $this->hasOne(Tag::className(), ['id' => 'tag_id']);
    }
    /**
     * @return \yii\db\ActiveQuery
     */
    public function getBlog()
    {
        return $this->hasOne(Blog::className(), ['id' => 'blog_id']);
    }

Теперь самое интересное. В классе BlogSearch для поиска записей добавляем переменную, которой нет в таблице

public $tag_id;

public function rules()
    {
        return [
            [['id', 'status', 'material_type', 'tag_id', 'author_id', 'count_views', 'sort'], 'integer'],
            ...
        ];
    }

Ниже в метод search дописываем with на связь taggs и joinWith, чтобы приджойнить значения теги

public function search($params, $section = null, $tag = null, $status = ['0','1'])
    {
        ...
        $query = Blog::find()->with('tagss')->joinWith(['blogTags'], false);
        ...

и чтобы заработал фильтр ниже допишем в него

$query->andFilterWhere([
            'id' => $this->id,
            'status' => $this->status,
            ...
            '{{%blog_tag_assn}}.tag_id' => $this->tag_id,
        ]);