How to Use Attach, Detach, and Sync in Laravel Eloquent
In Laravel Eloquent, use
attach to add related records, detach to remove them, and sync to replace existing relations with new ones. These methods work on many-to-many relationships defined by belongsToMany. They help manage pivot tables simply and cleanly.Syntax
These methods are called on a belongsToMany relationship to manage pivot table records:
attach($id, $attributes = [], $touch = true): Adds a relation by inserting a record in the pivot table.detach($id = null, $touch = true): Removes one or more relations from the pivot table.sync($ids, $detaching = true): Replaces existing relations with the given IDs, adding new and removing missing ones.
Here, $id or $ids can be a single ID, an array of IDs, or a collection.
php
public function roles() { return $this->belongsToMany(Role::class); } // Attach role(s) $user->roles()->attach($roleId); // Detach role(s) $user->roles()->detach($roleId); // Sync roles $user->roles()->sync([$roleId1, $roleId2]);
Example
This example shows how to attach, detach, and sync roles for a user in a many-to-many relationship.
php
<?php use App\Models\User; use App\Models\Role; // Find user and roles $user = User::find(1); $adminRole = Role::where('name', 'admin')->first(); $editorRole = Role::where('name', 'editor')->first(); // Attach admin role $user->roles()->attach($adminRole->id); // Detach editor role $user->roles()->detach($editorRole->id); // Sync roles to only admin and editor $user->roles()->sync([$adminRole->id, $editorRole->id]); // Output current roles foreach ($user->roles as $role) { echo $role->name . "\n"; }
Output
admin
editor
Common Pitfalls
- Calling
attachwith an ID already attached causes duplicate pivot entries unless the pivot table has unique constraints. - Using
detachwithout arguments removes all related records, which might be unintended. syncremoves all relations not in the given array, so be careful to include all desired IDs.- For extra pivot data, pass an associative array as the second argument to
attachorsync.
php
<?php // Wrong: detach without argument removes all roles $user->roles()->detach(); // Right: detach specific role $user->roles()->detach($roleId); // Wrong: attach duplicates if called twice $user->roles()->attach($roleId); $user->roles()->attach($roleId); // duplicates // Right: use sync to avoid duplicates $user->roles()->sync([$roleId]);
Quick Reference
| Method | Purpose | Parameters | Effect |
|---|---|---|---|
| attach | Add relation(s) | $id(s), attributes array | Inserts new pivot records, can add duplicates |
| detach | Remove relation(s) | $id(s) or none | Deletes pivot records; no argument removes all |
| sync | Replace relations | Array of $id(s) | Adds new, removes missing, keeps given only |
Key Takeaways
Use attach to add new related records in many-to-many relationships.
Detach removes specified relations or all if no ID is given, so use carefully.
Sync replaces all existing relations with the given list, adding and removing as needed.
Pass extra pivot data as an array in attach or sync to store additional info.
Avoid duplicates by preferring sync over multiple attach calls.