Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Yii2 - insert relational data with junction table, many-many connection

Tags:

yii2

I have a problem with Yii2 (Stable).

I have a Content(PK:id) table, I have a Tag(PK:id) table, and I have a junction table called Content_Tag (PK:content_id, tag_id). I'd like to use it for tagging, like WP tags.

All controllers and models are created with gii.

I have two problems:

If I create a new content, I'd like to save some new tags to the Tag table via the Content_Tag table. How can I do that? With link()?

What if there are tags (I know the ids) in the tag table, I'd like to connect only with the Content table via the junction table, without inserting into the Tag table. How can I do this?

I don't want to write native SQL command, I'd like to use the Yii2 built in functions like link() or via() or viaTable().

Thanks for your help!

like image 619
Adam Fentosi Avatar asked Oct 17 '14 04:10

Adam Fentosi


1 Answers

I created a behavior to help handle do this, basically you do:

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

You can get the behavior here: https://github.com/cornernote/yii2-linkall

If you'd prefer to do it without the 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);
    }
}
like image 180
cornernote Avatar answered Dec 25 '22 11:12

cornernote