0
0
LaravelHow-ToBeginner · 4 min read

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 attach with an ID already attached causes duplicate pivot entries unless the pivot table has unique constraints.
  • Using detach without arguments removes all related records, which might be unintended.
  • sync removes 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 attach or sync.
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

MethodPurposeParametersEffect
attachAdd relation(s)$id(s), attributes arrayInserts new pivot records, can add duplicates
detachRemove relation(s)$id(s) or noneDeletes pivot records; no argument removes all
syncReplace relationsArray 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.