【導入実績300社以上】AWS 構築・運用保守サービス

【導入実績300社以上】AWS 構築・運用保守サービス

【CMS】WordPress専用 クラウド / サーバー『WebSpeed』

【CMS】WordPress専用 クラウド / サーバー『WebSpeed』

【100URLの登録が0円】Webサイト監視サービス『Appmill』

【100URLの登録が0円】Webサイト監視サービス『Appmill』

【コミュニケーションアプリ開発】LINE アプリ開発サービス

【コミュニケーションアプリ開発】LINE アプリ開発サービス

【ECサイト構築】Shopify カスタムアプリ開発サービス

【ECサイト構築】Shopify カスタムアプリ開発サービス

【音声アプリ開発】Twilio アプリ開発サービス

【音声アプリ開発】Twilio アプリ開発サービス

【グローバル対応】北米リージョン・クラウド / サーバー サポート

【グローバル対応】北米リージョン・クラウド / サーバー サポート

【CPU】AMD EPYC 技術検証(PoC)サービス

【CPU】AMD EPYC 技術検証(PoC)サービス

【Webシステム / サービス開発】SEKARAKU Lab(セカラクラボ)

【Webシステム / サービス開発】SEKARAKU Lab(セカラクラボ)

【取材記事】サーバーサイド・バックエンドエンジニアを募集中

【取材記事】サーバーサイド・バックエンドエンジニアを募集中

【YouTube】ビヨンド公式チャンネル「びよまるチャンネル」

【YouTube】ビヨンド公式チャンネル「びよまるチャンネル」

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/

この記事がお役に立てば【 いいね 】のご協力をお願いいたします!
2
読み込み中...
2 票, 平均: 1.00 / 12
2,595
facebook twitter はてなブックマーク

この記事をかいた人

About the author

山田雄貴

2021年株式会社ビヨンド入社
趣味はカラオケやボードゲーム
ボードゲームのが一つの棚で収まりきらなくなったため、新しい棚を購入したいが、家に棚を置く場所が無く悲しんでいる。
金型の設計や営業の経験もあり、多種多様な経験を積みサーバーサイドエンジニアの仕事に落ち着いている。
現在はPHPやPythonを用いたサーバーサイドの開発に従事している。
将来的にはフロントエンドの言語も習得したく、ReactベースのフロントエンドフレームワークであるNext.jsが気になっている。