Sling Academy
Home/PHP/Laravel Eloquent: attach(), detach(), and sync() methods

Laravel Eloquent: attach(), detach(), and sync() methods

Last updated: January 17, 2024

Overview

Working with Laravel’s Eloquent ORM (Object-Relational Mapping) makes dealing with database relationships simple and elegant. Among the many powerful methods it provides for interacting with related models, particularly notable are attach(), detach(), and sync(). In this tutorial, we’ll explore how these methods can be used in managing many-to-many relationships with examples.

Before diving into code examples, you should have a foundational understanding of Eloquent relationships. Many-to-many relationships are where a model can be related to multiple instances of another model, and vice versa. For example, a User might ‘belong to’ many Roles, and a Role can be associated with many Users.

Setting Up a Many-to-Many Relationship

// User model
public function roles() {
    return $this->belongsToMany(Role::class);
}

// Role model
public function users() {
    return $this->belongsToMany(User::class);
}

You would typically have a pivot table associated with the relationship. For our User and Role example, this might be the role_user table.

Using attach()

The attach() method is used to create a new record on the pivot table, effectively linking the two models together.

$user = User::find(1);
$user->roles()->attach($roleId);

This will insert a new row in the role_user pivot table with the user’s ID and the role’s ID passed as $roleId. If you wish to attach multiple roles at once, you can pass an array of role IDs.

$user->roles()->attach([$roleId1, $roleId2, $roleId3]);

Using detach()

Opposite to attach(), detach() removes the relationship between the two models by deleting the corresponding record in the pivot table.

$user->roles()->detach($roleId);

You can also pass an array of IDs to detach multiple roles or call detach() without any arguments to detach all related roles.

$user->roles()->detach([$roleId1, $roleId2]);
$user->roles()->detach(); // Detaches all roles

Using sync()

The sync() method is used when you want to ensure only a specific list of IDs are attached to the model, removing any others. This is particularly useful when updating a model and you want to set the new list of related IDs, without needing to first call detach() and then attach() for the new ones.

$user->roles()->sync([$roleId1, $roleId3]);

The sync() method will handle removing any existing ties not in the given array, and adding the new ones. If you want to also keep the existing ties and only add new ones without removing any, you can use syncWithoutDetaching().

$user->roles()->syncWithoutDetaching($roleId4);

This will keep existing roles and add role 4, if it’s not already present. To pass additional data to the pivot table when using attach(), you can send a second parameter as an associative array.

$user->roles()->attach($roleId, ['expires' => $expiresDate]);

Handling Syncing Events

Laravel dispatches several events when attachments or detachments occur on a model relationship. These events, like attached, updated, and detached, can be used to perform additional logic or data integrity tasks when these actions take place.

To listen for these events, you can define methods on your model:

protected $dispatchesEvents = [
    'attached' => UserAttachedToRole::class,
    'detached' => UserDetachedFromRole::class,
];

Conclusion

attach(), detach(), and sync() are incredibly useful for managing many-to-many relationships within Laravel’s Eloquent ORM. Armed with these methods, you can easily build complex data associations and maintain them with clear and efficient code.

Remember also to leverage Eloquent’s ability to work with additional pivot data, handle events around syncing activities, and ensure relationships are easily managed within your application. Practice implementing these methods with different real-world scenarios to gain a better understanding of their functionality and use cases.

Enjoy coding and always keep exploring Laravel’s features to write less code while doing more!

Next Article: Laravel Eloquent: How to cast data types of model attributes

Previous Article: What are pivot tables in Laravel Eloquent: Explained with examples

Series: Laravel & Eloquent Tutorials

PHP

You May Also Like

  • Pandas DataFrame.value_counts() method: Explained with examples
  • Constructor Property Promotion in PHP: Tutorial & Examples
  • Understanding mixed types in PHP (5 examples)
  • Union Types in PHP: A practical guide (5 examples)
  • PHP: How to implement type checking in a function (PHP 8+)
  • Symfony + Doctrine: Implementing cursor-based pagination
  • Laravel + Eloquent: How to Group Data by Multiple Columns
  • PHP: How to convert CSV data to HTML tables
  • Using ‘never’ return type in PHP (PHP 8.1+)
  • Nullable (Optional) Types in PHP: A practical guide (5 examples)
  • Explore Attributes (Annotations) in Modern PHP (5 examples)
  • An introduction to WeakMap in PHP (6 examples)
  • Type Declarations for Class Properties in PHP (5 examples)
  • Static Return Type in PHP: Explained with examples
  • PHP: Using DocBlock comments to annotate variables
  • PHP: How to ping a server/website and get the response time
  • PHP: 3 Ways to Get City/Country from IP Address
  • PHP: How to find the mode(s) of an array (4 examples)
  • PHP: Calculate standard deviation & variance of an array