skip to Main Content

The error, I am observing, I try to put the old value i.e already stored. However, the case is, the old value get plucked with its own id, eachtime.

SQLSTATE[23000]: Integrity constraint violation: 19 UNIQUE constraint failed: tags.name (Connection: sqlite, SQL: insert into "tags" ("name", "user_id", "updated_at", "created_at") values (laravel, 1, 2024-12-13 05:16:56, 2024-12-13 05:16:56))

Here is what I am trying

$tag_ids = [];
foreach($tag_names as $tag_name) {//tag_names is array of tags
          
  $tag = Tag::firstOrCreate([ //Tag is a Model
    'name'      => $tag_name,
    'user_id'   => auth()->id(),
  ]);
 
  if($tag) {
    $tag_ids[] = $tag->id;
  }
}

Here is the Tag Model

class Tag extends Model {
    protected $guarded = [];

    public function user() {
        return $this->belongsTo(User::class);
    }
}

Here is the migration

Schema::create('tags', function (Blueprint $table) {
   $table->id();
   $table->string('name');
   $table->foreignId('user_id')->constrained();
   $table->timestamps();
});

2

Answers


  1. To synchronise the tags you can use a single query insertOrIgnore() and use another one to retrieve the ids.

    $to_be_upserted = [];
    foreach($tag_names as $tag_name) {
        $to_be_upserted[] = ['name' => $tag_name, 'user_id' => auth()->id()];
    }
    Tag::query()->insertOrIgnore($to_be_upserted, []);
    //here all the tags are present in DB
    
    $tag_ids = Tag::query()->where('user_id', auth()->id())
        ->whereIn('name', $tag_names)
        ->pluck('id')->toArray();
    
    

    If you get the mass assignment exception. You will need to add the fields name and user_id to the Tag model fillable attribute.

    class Tag extends Model
    {
        $fillable = ['name','user_id'];
    //...
    }
    
    Login or Signup to reply.
  2. I see that you want to collect tag_id based on tag_name, so as stated here, I suggest something using firstOrCreate as follows

    $tag_ids = [];
    foreach($tag_names as $tag_name) {//tag_names is array of tags
              
      $tag = Tag::firstOrCreate(
        ['name'      => $tag_name],
        ['user_id'   => auth()->id()]
      );
     
      if($tag) {
        $tag_ids[] = $tag->id;
      }
    }
    

    by doing this, it will find by name or create it with name and user_id.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search