Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

kfirba's avatar
Level 50

Eloquent - sync(), associate()

Hello!

I'm kinda struggling understanding those methods. I'm not sure how sync() differs from attach() and why would I use associate() instead of just the save() method.

Any clarification will be appreciated :)

0 likes
11 replies
usman's avatar

Afaik, associate works from the belongsTo side of the relationship, for instance you can associate an author with a book like:

//this sets the author_id (the parent model) on the book table
$book->author()->associate($someAuthorModelInstance);
//we still need to save the $book
$book->save();

sync can be used to synchronize the either side of a belongsToMany relationship, by default it drops all the relations and just keep those provided as the arguments:

//this will drop all the existing roles except the roles with id 1,2,3. If these ids don't exist it will attach them (still dropping the existing ones).
$user->roles()->sync([1,2,3]);
//the default behaviour can be changed by passing a 'false' as a second argument.
//this will attach the roles with ids 1,2,3 without affecting the existing roles.
//in this mode sync behaves similar to the attach method.
$user->roles()->sync([1,2,3], false);

Usman.

18 likes
Charkhan's avatar

With sync, you actually "sync" the data you provide with the DB.

Let's say you want to sync posts to a user :

<?php
//Assume you have Post 2 & 4 attached to the User

//The User has now Post 1 & 3  ONLY attached (2 & 4 were removed)
User::find($someUser)->posts()->sync([1, 3]);

//OR assume you have Post 2 & 4 attached to the User
//The attach counterpart : The user has Post 1, 2, 3, 4 attached.
User::find($someUser)->posts()->attach(1);
User::find($someUser)->posts()->attach(3);

sync() will keep in DB the IDs you pass to it, where attach() add to the existing data.

5 likes
kfirba's avatar
Level 50

@usman @usman Thanks. That seems to explain the sync method.

BTW, I'm pretty sure you can do something like:

User::find(1)->posts()->attach([1,2,5,8]);

About the associate() method, why can't I simply do something like:

$book->authors()->create($authorArray);
usman's avatar

About the associate() method, why can't I simply do something like: $book->authors()->create($authorArray);

In the context of a one to many | belongsTo relation, it is by design I think, we cannot create parent models from the child side of the relation.

But in a many to many context | belongsToMany, I am pretty sure we can do this. ref: https://github.com/laravel/framework/blob/5.0/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php#L593-L604

Btw, have you noticed the 5 in the url? :)

JarekTkaczyk's avatar

@kfirba You're right, you can provide an array of ids for both attach and sync.

But there's more than what has been already said and that's why sync is most of the times preferable, especially that most likely you don't need duplicate pivot associations:

// attach new pivot records, each with `pivot_column = pivot_data`
$model->mmrelation()->attach([1,2,3], ['pivot_column' => 'pivot_data']);

// this will add new & update existing pivot records, each with different `pivot_data`
$model->mmrelation()->sync( [
   1 => ['pivot_column' => 'pivot_data_1'],
   2 => ['pivot_column' => 'pivot_data_2'],
   3 => ['pivot_column' => 'pivot_data_3']
], false)

Also you can do this, tho this just adds some sugar, no real difference:

$model->mmrelation()->attach($modelInstance);
$model->mmrelation()->sync($EloquentCollectionOfModels);
5 likes
kfirba's avatar
Level 50

@JarekTkaczyk I see.

So if we are talking about one-to-many relationship, it means that I cannot create a "parent" (author) model from the "child" (book) model but I have to associate the "child" (book) model with an existing "parent" (author) model? Does it mean I can indeed do something like:

$author->books()->create();

but not

$book->author()->create();
// but i can do
$book->author()->associate($anAuthorModel);
1 like
JarekTkaczyk's avatar

@kfirba exactly. This is a little summary of available methods for association / creation and association:

 * hasOne / hasMany (1-1, 1-M)
    -save(new or existing child)
    -saveMany(array of models new or existing)
    -create(array of attributes)
    -createMany(array of arrays of attributes)
    ---------------------------------------------------------------------------

 * belongsTo (M-1, 1-1)
    -associate(existing model)
    ---------------------------------------------------------------------------

 *  belongsToMany (M-M)
    -save(new or existing model, array of pivot data, touch parent = true)
    -saveMany(array of new or existing model, array of arrays with pivot ata)
    -create(attributes, array of pivot data, touch parent = true)
    -createMany(array of arrays of attributes, array of arrays with pivot data)
    -attach(existing model / id, array of pivot data, touch parent = true)
    -sync(array of ids OR ids as keys and array of pivot data as values, detach = true)
    -updateExistingPivot(relatedId, array of pivot data, touch)
    ---------------------------------------------------------------------------

 *  morphTo (polymorphic M-1)
    // the same as belongsTo
    ---------------------------------------------------------------------------

 *  morphOne / morphMany (polymorphic 1-M)
    // the same as hasOne / hasMany
    ---------------------------------------------------------------------------

 *  morphedToMany /morphedByMany (polymorphic M-M)
    // the same as belongsToMany

54 likes
JarekTkaczyk's avatar

@kfirba tags are probably the best example. You can tag different things like Post , Category etc and of course multiple tags can be used for multiple taggables. I think in the docs is shown something like this as well.

2 likes
gildniy's avatar

@JarekTkaczyk thanks for clarifying the real use of "association / creation" methods, this really helps because I was wondering whether we can do something like this: (Which was not mentioned in the Doc)

$tag->attach($photos); // Seeming to be on a reverse side of M-M Polymorphic
$tag->save();

Before you explain this I was thinking to loop some thing like:

if ($photos) {
            foreach ($photos as $photo) {
                $photo->attach($tag);
            }
        }
$tag->save();

And the later which was not yet verified could be also be very slow. Again you prove, you are a hero in Eloquent war! Tx

burakcalik2's avatar

@JarekTkaczyk This is the most beautiful and useful explanation ever. Thanks. Laravel docs should also use that.

1 like

Please or to participate in this conversation.