Laravelでは、中間テーブルに複数の値を一度に保存することができます。
中間テーブルに保存用のフォームの作成方法も併せて、手順を解説していきますね。
Laravelの中間テーブルは便利です。
ぜひ、色々な使い方をおさえていきましょう♪
Laravelで中間テーブルに複数の値を保存する方法
まずプロジェクトを作成する等、準備をお願いします。
こちらの記事の④あたりまで進めておいてください。
(中間テーブルには、値を保存しなくてOKです。)
このあとの手順を解説します。
① ルート設定を作成する
フォーム表示用と保存用の2つを作成します。
【web.php】
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\ClubController; // 表示用 Route::get('/dashboard', [ClubController::class, 'index'])->name('dashboard'); // 保存用 Route::post('/post', [ClubController::class, 'store'])->name('club.store'); Route::get('/', function () { return view('welcome'); }); |
② コントローラーを作成する
下記のコマンドを入力して、コントローラーを作成します。
1 |
php artisan make:controller ClubController |
作成した ClubControllerを開きます。
フォームを表示するためのindexメソッドを追加します。
【ClubController.php】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Club; class ClubController extends Controller { public function index() { $clubs=Club::all(); return view('dashboard', compact('clubs')); } } |
③ ビューファイルを作成する
resources/view/dashboard.blade.php の中に、次のようにフォームを作成します。
【dashboard.blade.php】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<form method="post" action="{{route('club.store')}}" enctype="multipart/form-data"> @csrf <div class="mb-4"> <select name="club_id" class="block appearance-none bg-white border border-gray-400 hover:border-gray-500 px-4 py-2 pr-8 rounded shadow leading-tight focus:outline-none focus:shadow-outline" required> @foreach($clubs as $club) <option value="{{$club->id}}">{{$club->name}}</option> @endforeach </select> </div> <div class="mb-4"> <label for="note" class="block text-gray-700 text-sm font-bold mb-2">ユーザーにとっての位置づけ</label> <input class="shadow appearance-none border rounded py-2 px-3 text-gray-700" type="text" name="note" class="form-control" id="note" value="{{old('note')}}" placeholder="位置づけ"> </div> <button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline" type="submit"> 送信する </button> </form> |
ブラウザに表示すると、次のようになります。
なお上記コードでは、CSSはTailwindを使っています。環境によって、classの部分は変えてくださいね。
④ 保存用のコードをつくる
再びClubControllerを開きます。
フォームを保存するためのstoreメソッドを追加します。
【ClubController.php】
1 2 3 4 |
public function store(Request $request) { auth()->user()->clubs()->attach($request->club_id, ['note' => $request->note]); return back(); } |
最初にレコードのid部分を指定します。そのあと、レコードの各カラムにいれる値を連想配列の形で指定します。
なお今回はattachメソッドを使いました。attachは、同じ値の重複保存も可能です。
重複を避けたい場合は、syncメソッドを使ってくださいね。
多対多のリレーションで中間テーブルに値を保存する方法は、こちらの記事にまとめています。
⑤ テストをする
それでは、いよいよテストです。
ブラウザに値をいれて、きちんと中間テーブル club_userに保存されるか、チェックしてみてください。
⑥ おまけ:中間テーブル保存時にタイムスタンプも追加する方法
なお、デフォルトのままだと中間テーブルに保存したとき、タイムスタンプカラム(created_at, updated_at) に値が入りません。
タイムスタンプに値をいれるようにするには、リレーションを設定する際に、次のようにwithTimestampsを追加します。
【User.php】
1 2 3 4 5 |
public function clubs() { return $this->belongsToMany('App\Models\Club') ->withPivot('note') ->withTimestamps(); } |
withTimestampsを加えると、中間テーブルに、次のようにcreated_at、updated_atカラムに日時情報が入ります。
【club_userテーブル】
以上となります。
Laravelのリレーションに関する記事は他にも色々あるので、参考にしてくださいね。
まずは基本の中間テーブルの作成方法を知りたい方はこちらをどうぞ。