[Osaka/Yokohama] Looking for infrastructure/server side engineers!

[Osaka/Yokohama] Looking for infrastructure/server side engineers!

[Deployed by over 500 companies] AWS construction, operation, maintenance, and monitoring services

[Deployed by over 500 companies] AWS construction, operation, maintenance, and monitoring services

[Successor to CentOS] AlmaLinux OS server construction/migration service

[Successor to CentOS] AlmaLinux OS server construction/migration service

[For WordPress only] Cloud server “Web Speed”

[For WordPress only] Cloud server “Web Speed”

[Cheap] Website security automatic diagnosis “Quick Scanner”

[Cheap] Website security automatic diagnosis “Quick Scanner”

[Reservation system development] EDISONE customization development service

[Reservation system development] EDISONE customization development service

[Registration of 100 URLs is 0 yen] Website monitoring service “Appmill”

[Registration of 100 URLs is 0 yen] Website monitoring service “Appmill”

[Compatible with over 200 countries] Global eSIM “Beyond SIM”

[Compatible with over 200 countries] Global eSIM “Beyond SIM”

[If you are traveling, business trip, or stationed in China] Chinese SIM service “Choco SIM”

[If you are traveling, business trip, or stationed in China] Chinese SIM service “Choco SIM”

[Global exclusive service] Beyond's MSP in North America and China

[Global exclusive service] Beyond's MSP in North America and China

[YouTube] Beyond official channel “Biyomaru Channel”

[YouTube] Beyond official channel “Biyomaru Channel”

Laravelで中間テーブルを使いたい! syncメソッドの使い方

お疲れ様です!
システム開発部の山田です。

今回は、Laravelで中間テーブルを用いる際に使用するsyncメソッドについて解説していきます。

syncメソッドとは?

テーブルの関係性が多対多の場合、解決法として基本的に中間テーブルを用いると思います。
その際に、中間テーブルへのデータ登録や更新、削除といった動作をsyncメソッドを用いることで簡単に行うことができる優れものです。
具体的な実例とともに見ていきます。

準備(テーブル構成)

syncメソッドの使用にあたり以下状況を想定します。

  • ユーザーと趣味を紐づけ関係性にコメントを付与したい
  • 1ユーザーは趣味を複数持つことができる
  • 1 つの趣味は複数のユーザーから選ばれる

上記を達成するためのテーブル構成は以下を想定します。

  • ユーザーの名前を保持するusersテーブル
id name
1 taro
2 hanako
3 saburo
  • 趣味を名称を保持するhobbiesテーブル
id name
1 映画
2 youtube
3 勉強
  • ユーザーと趣味を関係を表し、コメントを付与できる中間テーブル(hobby_userテーブル
id user_id hobby_id comment
1 1 1 結構すき
2 1 2 そこそこすき
3 2 1 結構すき

以上内容でLaravelでマイグレーションファイルを用意し、users、hobbiesテーブルには記載しているデータを挿入した前提で以降の話を進めます。

準備(Laravelのモデルファイル)

Laravelのモデルファイルに多対多の関係性を表すために以下を記述します。

// hobbyモデル
public function users()
{
    return $this->belongsToMany(User::class);
}

// usersモデル
public function hobbies()
{
    return $this->belongsToMany(Hobby::class);
}

以上よりsyncメソッドの使用準備が整いましたので以降より使用していきます。

syncメソッド

それでは、まずはデータの登録を行いたいと思います。
taro(user_id:1)の趣味に映画(hobby_id:1)を追加したい場合は以下で表せます。

$user = User::find(1);
$user->hobbies()->sync(1);

コメントや複数の登録を一度に行いたい場合は、以下で表せます。
taro(user_id:1)の趣味にyoutube(hobby_id:2)、勉強(hobby_id:3)を追加しコメントも記載を想定します。

$user = User::find(1);
$user->hobbies()->sync([
    2 => ['comment' => '結構すき'],
    3 => ['comment' => 'そこそこすき'],
]);

ただし、ここで注意点があります。
以下は先ほどのtaro(user_id:1)の趣味に映画(hobby_id:1)を追加した状態のDBに
今回のコードを実行した場合のDBです。

taro(user_id:1)の趣味に映画(hobby_id:1)を追加したデータが消えております。
これはsyncメソッドが名前の通り、データの状態を指定した内容で同期を行うメソッドであるためです。
※sync: 同調・同期

この同期する性質を利用することでデータの削除、更新も簡単に行うことができます。
taro(id:1)の趣味を以下に変更する事を考えます。
youtube(hobby_id:2)、勉強(hobby_id:3)⇒映画(hobby_id:1)、youtube(hobby_id:2)

現状のDBは以下になります。

これを以下コードを実行した場合

$user = User::find(1);
$user->hobbies()->sync([1,2]);

結果は以下になります。

本来であれば勉強(hobby_id:3)の削除⇒映画(hobby_id:1)の追加を行うところを、syncメソッドを用いることで一発で行うことができました。
また、挙動として知っておきたい箇所はid=2の部分です。
コメントは今回指定していませんが、そのまま残っております。
これは、同期するのはあくまでも指定したuser_idとhobby_idの関係性であり、hobby_id=2は変更する必要が無いため、レコードを更新や削除がされることなく、そのまま残っているためです。

syncメソッドの応用

syncメソッドは、同期するメソッドであると説明しましたが、実は同期をせずに登録のみを行うことも可能です。
その方法は第二引数にfalseを宣言する事です。
先ほどのテーブルに続きに、taro(id:1)の趣味に勉強(hobby_id:3)を追加してみます。

$user = User::find(1);
$user->hobbies()->sync(3, false);

第二引数にfalseを指定することで、元々存在していた映画(hobby_id:1)、youtube(hobby_id:2)は消えることなく、勉強(hobby_id:3)の追加に成功しました。
ただし、falseをつけるのは忘れやすい行動で、もし指定を行わなかった場合は意図せずデータを消す恐れがあります。
そのため、falseを指定する代わりにsyncWithoutDetachingメソッドを指定しても同様の内容を表します。

$user = User::find(1);
$user->hobbies()->syncWithoutDetaching(3);

まとめ

今回はLaravelで中間テーブルの登録や変更、削除を行う際に便利なsyncメソッドを紹介しました。
同期の性質を理解する事さえできれば非常に扱いやすいメソッドだと思います。
また、最後に紹介したsyncWithoutDetachingメソッドはlaravelの内部的にはsyncメソッドにfalseを指定した物を実行するだけですが、
こういった物が用意されている事で、うっかりミスを防ぐことができるので非常に使い勝手のいいメソッドですね。

皆さんもsyncメソッドを使いこなし、日々コーディングを楽しんで行いましょう!
それでは!!

最後に

私が所属するシステム開発のサービスサイト「SEKARAKU Lab(セカラク ラボ)」を開設しました。
ビヨンドは、サーバーの設計・構築から運用までをワンストップでお任せいただけますので、サーバーサイド開発でお困りの方はお気軽にお問い合わせください。
SEKARAKU Lab:https://sekarakulab.beyondjapan.com/

この記事がお役に立てば【 いいね 】のご協力をお願いいたします!
5
読み込み中...
5 票, 平均: 1.00 / 15
11,715
X facebook はてなブックマーク pocket
[2024.6.30 CentOS support ended] CentOS server migration solution

[2024.6.30 CentOS support ended] CentOS server migration solution

[2025.6.30 Amazon Linux 2 support ended] Amazon Linux server migration solution

[2025.6.30 Amazon Linux 2 support ended] Amazon Linux server migration solution

[Osaka/Yokohama] Actively recruiting infrastructure engineers and server side engineers!

[Osaka/Yokohama] Actively recruiting infrastructure engineers and server side engineers!

The person who wrote this article

About the author

Yuki Yamada

Joined Beyond Co., Ltd. in 2021
My hobbies are karaoke and board
games.My board games can no longer fit on one shelf, so I would like to buy a new shelf, but I am sad because I don't have a place to put a shelf at home.
He has experience in mold design and sales, and has gained a wide variety of experience and has settled into a job as a server-side engineer.
He is currently working on server-side development using PHP and Python.
He also wants to learn a front-end language in the future, and is interested in Next.js, a React-based front-end framework.