I am working on a plugin and I have the following code

private function _tagProducts(array $products, array $names)
    foreach ($products as $productId)
        $product = Craft::$app->getElements()->getElementById($productId, Product::class, null);
        $product['businessTag'] = ['something'];
        $product['purchasedWithVoucher'] = 'no';

If I remove/comment out the line $product['businessTag'] = ['something']; this snippet runs just fine and updates the field purchasedWithVoucher just fine. But, if I keep the businessTag line in I get the following error.

(Integrity constraint violation – yii\db\IntegrityException)

I have tried updating the tag field as $product['businessTag'] = 'something'; which at least throws no errors, but the product is not updated with the new tag, however the $product['purchasedWithVoucher']; line does update so I know that simply saving the changes isn't the issue.


The trick here is that Tags are also elements, so you'll need to save them or look them up to assign them. Something like this:

    public function createOrGetTag($keyword, $groupId) {
        $tagQuery = new TagQuery(Tag::class);
        $tagQuery->groupId = $groupId;
        $tagQuery->title = $keyword;
        $tag = $tagQuery->one();

        if (!$tag) {
            $tag = new Tag();
            $tag->groupId = $groupId;
            $tag->title = $keyword;

        return $tag;

And then in your field setting, you'd do something like this:

$product->businessTag->id[] = $tag->id;
  • Sorry about all the comments and deleted comments. I had done something wrong and messed up the code when I put it in and it didn't work, then found a solution I thought worked but only made a mess. I still am though, stuck on the last line $product->businessTag->id[] = $tag->id; it successfully updates the product with the tag but it overwrites all other tags. Feb 1 '19 at 16:50

I had an issue with Ransom Roberson code $product->businessTag->id[] = $tag->id; but otherwise everything else worked. The problem is the snippet above will update the tag and then overwrite every tag the entry/product has. So I wrote the code below. Ransom's code works perfectly aside from the last part, so putting this with it should help anyone in the future who is might struggle with this.

$existingTags = $product->businessTag->ids();

    foreach ($existingTags as $eTag)
        $product->businessTag->id[] = $eTag;

    $product->businessTag->id[] = $tag->id

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.