How to use intermediate tables in Laravel! How to use the sync method

table of contents
Hello!
This is Yamada from the Systems Development Department.
This time, we will explain the sync method used when using intermediate tables in Laravel
What is the sync method?
When tables have a many-to-many relationship, the basic solution is to use an intermediate table.
The `sync` method is excellent for easily performing operations such as adding, updating, and deleting data in the intermediate table.
Let's look at some concrete examples.
Preparation (table layout)
When using the sync method, the following situations are assumed:
- I want to link users with their hobbies and add comments to their relationships
- One user can have multiple hobbies
- A hobby is chosen by multiple users
The table configuration to achieve the above is assumed to be as follows
- A users table that holds the names of users
| id | name |
|---|---|
| 1 | Taro |
| 2 | Hanako |
| 3 | saburo |
- A hobbies table that holds the names of hobbies
| id | name |
|---|---|
| 1 | movie |
| 2 | YouTube |
| 3 | study |
- An intermediate table (hobby_user table) that represents the relationship between users and hobbies and allows comments to be added)
| id | user_id | hobby_id | Comment |
|---|---|---|---|
| 1 | 1 | 1 | I quite like it |
| 2 | 1 | 2 | I like it quite a bit |
| 3 | 2 | 1 | I quite like it |
We will proceed with the following discussion assuming that you have prepared a migration file in Laravel with the above information and inserted the data described in the users and hobbies tables
Preparation (Laravel model file)
To represent a many-to-many relationship in a Laravel model file, write the following:
// hobby model public function users() { return $this->belongsToMany(User::class); } // users model public function hobbies() { return $this->belongsToMany(Hobby::class); }
Now that we are ready to use the sync method, we will start using it from here
sync method
First, let's register the data.
If you want to add "movies" (hobby_id:1) to taro's (user_id:1) hobbies, you can express it as follows:
$user = User::find(1); $user->hobbies()->sync(1);

If you want to add comments or register multiple items at once, you can do so as follows.
Let's assume that taro (user_id:1) has added youtube (hobby_id:2) and studying (hobby_id:3) to their hobbies and also writes a comment.
$user = User::find(1); $user->hobbies()->sync([ 2 => ['comment' => 'I like it quite a bit'], 3 => ['comment' => 'I like it moderately'], ]);
However, there is a point to note here.
on the database where "movies" (hobby_id:1) has been added to the hobbies of taro (user_id:1) mentioned earlier
is the database when this code is executed

The data indicating that "movies" (hobby_id:1) was added to taro's (user_id:1) hobbies has disappeared.
This is because the sync method, as its name suggests, synchronizes the state of data according to the specified content.
*sync: synchronization
By utilizing this synchronization property, data deletion and updating can be easily performed.
Let's consider changing taro(id:1)'s hobbies as follows:
youtube(hobby_id:2), studying(hobby_id:3) ⇒ movies(hobby_id:1), youtube(hobby_id:2)
The current DB is as follows:

If you run the following code:
$user = User::find(1); $user->hobbies()->sync([1,2]);
The results are as follows:

Normally, this would involve deleting "study" (hobby_id:3) and then adding "movie" (hobby_id:1), but using the sync method allowed us to do it in one step.
Also, it's important to be aware of the behavior of the id=2 part.
Although we didn't specify a comment this time, it remains as is.
This is because the synchronization only affects the relationship between the specified user_id and hobby_id, and hobby_id=2 does not need to be changed, so the record is not updated or deleted and remains as is.
Application of the sync method
I explained that the `sync` method is a method for synchronization, but it is actually possible to register data without synchronization.
The way to do this is to declare `false` as the second argument.
Following the table from before, let's add "studying" (hobby_id:3) to the hobbies of taro (id:1).
$user = User::find(1); $user->hobbies()->sync(3, false);

By specifying `false` as the second argument, the existing entries for movies (hobby_id:1) and YouTube (hobby_id:2) were not deleted, and the addition of "studying" (hobby_id:3) was successful.
However, specifying `false` is an easy action to forget, and if you don't specify it, you may unintentionally delete data.
Therefore, specifying the `syncWithoutDetaching` method instead of `false` will achieve the same result.
$user = User::find(1); $user->hobbies()->syncWithoutDetaching(3);
summary
This time, I introduced the `sync` method, which is useful for registering, modifying, and deleting intermediate tables in Laravel.
I think it's a very easy method to use as long as you understand the nature of synchronization.
Also, the `syncWithoutDetaching` method that I introduced at the end is internally just the `sync` method with `false` specified, but
having such a method available helps prevent accidental mistakes, making it a very convenient method.
Let's all master the sync method and enjoy coding every day!
See you soon!!
lastly
I have launched "SEKARAKU Lab," a service website for the system development company I belong to.
Beyond offers a one-stop service for everything from server design and construction to operation, so please feel free to contact us if you have any problems with server-side development.
SEKARAKU Lab:https://sekarakulab.beyondjapan.com/
6
