Laravelでは、中間テーブルに複数の値を一度に保存することができます。
中間テーブルに保存用のフォームの作成方法も併せて、手順を解説していきますね。

Laravelの中間テーブルは便利です。
ぜひ、色々な使い方をおさえていきましょう♪
Laravelで中間テーブルに複数の値を保存する方法
まずプロジェクトを作成する等、準備をお願いします。
こちらの記事の④あたりまで進めておいてください。
(中間テーブルには、値を保存しなくてOKです。)
このあとの手順を解説します。
① ルート設定を作成する
フォーム表示用と保存用の2つを作成します。
【web.php】
<?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');
});
② コントローラーを作成する
下記のコマンドを入力して、コントローラーを作成します。
php artisan make:controller ClubController
作成した ClubControllerを開きます。
フォームを表示するためのindexメソッドを追加します。
【ClubController.php】
<?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】
<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】
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】
public function clubs() {
return $this->belongsToMany('App\Models\Club')
->withPivot('note')
->withTimestamps();
}
withTimestampsを加えると、中間テーブルに、次のようにcreated_at、updated_atカラムに日時情報が入ります。
【club_userテーブル】

以上となります。
Laravelのリレーションに関する記事は他にも色々あるので、参考にしてくださいね。
まずは基本の中間テーブルの作成方法を知りたい方はこちらをどうぞ。





コメント