フォームで新規登録を行うときに、Pivot中間テーブルにも簡単にデータを保存する方法を紹介します。
中間テーブルにデータを保存する時には、 attach関数を使うと便利です。
Pivotで役立つattach, sync, detach関数を、実際のコードを使って解説していきますね。
Laravel フォームから中間Pivotテーブルにデータ保存【attach・sync】
実現したいこと
ユーザーテーブルとロールテーブルの間に、中間テーブルを作ってあるとします。
フォームを作り、ユーザー新規登録時にユーザーのロールも登録するようにします。
フォームの【登録】ボタンを押すと、下記の形で、ふたつのテーブルにデータが保存されるようにします。
- ユーザーテーブルにはユーザーの名前・メールアドレス・パスワードを保存
- 中間テーブルにはユーザーのIDとロールIDを保存
belongToManyリレーションを構築
あらかじめblongToManyリレーションを使って、中間テーブルを用意しておきましょう。
下記記事で詳しく手順を説明しているので、参考にしてください。
モデルファイルには、リレーションを作るために次のように記述しておきます。
【User】
1 2 3 |
public function roles(){ return $this->belongsToMany('App\Models\Role'); } |
【Role】
1 2 3 |
public function users(){ return $this->belongsToMany('App\Models\User'); } |
フォーム作成のポイント
新規ユーザーを登録する時に、ロールも選択する形にします。
ロール部分のコードは次のように記述します。
フォーム作成時のポイントは下記2点
- nameには【role_id】という値を入れておきます。
- valueにも【role->id】を設定しておきます。
コントローラーへの記述【attach】
コントローラーにはattachを使って保存のコードを書きます。
1 |
$user->roles()->attach($roleId); |
全体は次のようになります。
コントローラーを記述する際のポイントは下記2点。
- 中間テーブルへの保存は、ユーザーの保存の後に記述する。
- 中間テーブルへの保存には【attach】関数を使う。
attach関数は、多対多のリレーション用にLaravelが用意してくれているヘルパ関数。
attach を使うと、簡単に中間テーブルにデータを挿入できます。
公式マニュアルには、次のように書かれています。
多対多リレーションを操作時により便利なように、Eloquentはヘルパメソッドをいくつか用意しています。(略)
モデルを結びつけている中間テーブルにレコードを挿入することにより、ユーザーに役割を持たせるにはattachメソッドを使います。
*引用元:公式マニュアル
コントローラーへの記述【sync】
attachを使うと、Pivotテーブル内にデータの重複が起こります。
もしテーブル内の値を重複させたくないときは、syncを使います。
1 |
$user->roles()->sync($roleId, false); |
全体は次のようになります。
これで、同じユーザーが同じロールをもつデータが重複登録されることはなくなります。
ただし、同じユーザーが複数のロールを持つことは可能です。
削除するときは【detach】
あるroleやuserを削除するときには、Pivotテーブルにも反映させておきましょう。
こういった場合に使えるのが 【detach】。
1 |
$user->roles()->detach($roleId); |
IDを指定しない場合はこちら。
1 |
$user->roles()->detach(); |
detachによって、連携を解除させることができます。
detachを行っても、各モデルのテーブルの値は削除されません。
反対にdetachを行わないと、実体を削除しても、Pivotテーブル上にだけデータが残ってしまいます。
さいごに
無事、あなたの実現したいことができることを願ってます!
Laravelのリレーションは他の記事でも紹介しているので、良かったら併せて見てみてくださいね。
コメント
はじめまして。
Laravel8を勉強中にこちらの記事を見つけました。
大変参考になり助かっております。
ありがとうございます。
少し質問がありましてコメントをさせていただきました。
記事中の中間テーブルに「withPivot」でカラムを追加して
追加カラムを含めたフォームからの登録や、データ表示というのはどのようにすると良いでしょうか?
今私がそこのあたりで壁となっており行き詰まりを感じておりましたので
いきなり失礼かと存じますが、もし記事作成のネタになりそうでしたら嬉しく思います。
どうぞよろしくお願いいたします。
温かいコメントありがとうございます!
中間テーブル、便利ですよね。
withPivotの使い方・中間テーブルへの登録方法、記事にしました。
★withPivot
https://biz.addisteria.com/laravel_withpivot/
★中間テーブルへの登録方法
https://biz.addisteria.com/laravel_pivot_store/
お返事遅れましたが、ご参考になれば嬉しいです。
この度は記事にしてくださり誠にありがとうございます。
早速勉強をさせていただきます。
これからもブログやYOUTUBEがんばってください。
応援しています。
ありがとうございます!!