Yii2 - insert relational data with a join table, many-many join

I have a problem with Yii2 (Stable).

I have a Content table (PK: id), I have a Tag table (PK: id), and I have a Content_Tag connection table (PK: content_id, tag_id). I would like to use it for tagging, for example, WP tags.

All controllers and models are created using gii.

I have two problems:

If I create new content, I would like to save some new tags in the tag table via the Content_Tag table. How can i do this? With a link ()?

What if there are tags in the tag table (I know the identifiers), I would like to connect only to the content table through the connection table, without inserting them into the tag table. How can i do this?

I don’t want to write my own SQL command, I would like to use the Yii2 built-in functions such as link () either via () or via Tab ().

Thank you for your help!

+6
source share
2 answers

I created a behavior to help deal with this, basically you:

$content = Content::findOne(1); $tags = [Tag::findOne(2), Tag::findOne(3)]; $content->linkAll('tags', $tags, [], true, true); 

Here you can get the following: https://github.com/cornernote/yii2-linkall

If you prefer to do this without behavior, something like this:

 // get the content model $content = Content::findOne(1); // get the new tags $newTags = [Tag::findOne(2), Tag::findOne(3)]; // get the IDs of the new tags $newTagIds = ArrayHelper::map($newTags, 'id', 'id'); // get the old tags $oldTags = $post->tags; // get the IDs of the old tags $oldTagIds = ArrayHelper::map($oldTags, 'id', 'id'); // remove old tags foreach ($oldTags as $oldTag) { if (!in_array($oldTag->id, $newTagIds)) { $content->unlink('tags', $oldTag, true); } } // add new tags foreach ($newTags as $newTag) { if (!in_array($newTag->id, $oldTagIds)) { $content->link('tags', $newTag); } } 
+2
source

If you created models using gii, then you can see in the model that relations are performed as follows:

  /** * @return \yii\db\ActiveQuery */ public function getContent() { return $this->hasMany(Content_Tag::className(), ['content_id' => 'id']); } /** * @return \yii\db\ActiveQuery */ public function getContent() { return $this->hasMany(Tag::className(), ['tag_id' => 'tag_id'])->viaTable('content_tag', ['content_id' => 'id']); } 

If you want to save the table Content_Tag based on the table of content and tags, then in the controller you can use:

 public function actionCreate() { $model = new Tag(); $content = new Content(); $content_tag = new Content_tag(); if($model->load(Yii::$app->request->post()) && $model->save()){ $model->save(false); $content_tag->tag_id = $model->id; $content_tag->content_id = $model->content_id; $content_tag->save(false); if($model->save(false)) { Yii::$app->getSession()->setFlash('success', 'Created successfully'); return $this->render('create',[ 'model' => $model, 'content' => $content, 'content_tag' => $content_tag ]); } } else { return $this->render('create', [ 'model' => $model, ]); } } 

You can use the link () to save. I am also looking for this as I have not used this.

0
source

Source: https://habr.com/ru/post/976855/


All Articles