Laravelで中間テーブルの値を取得するなら、withPivotが使えます。
中間テーブルの作成、リレーションの設定方法も含め、withPivotの使い方を解説しますね。
中間テーブルは、とにかく便利です。
色んな技を頭の中にいれておいて、いざというとき、取り出していきましょう♪
Laravelで中間テーブルの値を取得するならwithPivotが使える
今回は、次のような形でデータベースを作成します。
【今回使うデータベーステーブル】
なおLaravelのプロジェクト、ログイン認証機能は既に搭載済みという前提で解説します。
Userテーブルは、デフォルトであるものを利用します。
本記事を通じて、Clubテーブルを新たに作り、さらにUserテーブルとClubテーブルの中間テーブルを作成します。
このデータベースに格納したデータを使って、次のような画面を作成します。
【今回作成する画面】
ログインしたユーザーの所属しているクラブ、活動日、そしてユーザーにとってのクラブの位置づけが表示される形です。
このクラブの位置づけ情報は、中間テーブルのnoteカラムに入っています。
【withPivotを使って取り出すカラムはここ!】
それでは、ひとつずつ手順を説明していきますね。
① Clubモデルとテーブルを作る
下記コマンドでClubモデルとテーブルを作成します。
1 |
php artisan make:model Club -m |
Clubモデルには、次のようにリレーションを設定しておきます。
【App\Models\Club】
1 2 3 |
public function users() { return $this->belongsToMany('App\Models\User'); } |
マイグレーションファイルには、次のようにいれます。
【database/migrations/日付_create_clubs_table.php】
1 2 3 4 5 6 7 8 9 |
public function up() { Schema::create('clubs', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('day'); $table->timestamps(); }); } |
ファイルを保存後、php artisan migrate を実行します。
② Userモデルを編集する
Userモデルには、次のようにいれておきます。
【App\Models\User】
1 2 3 4 |
public function clubs() { return $this->belongsToMany('App\Models\Club') ->withPivot('note'); } |
ここで、withPivot使っています。
上記のように書くことで、中間テーブル(pivot)の中のカラム、noteを簡単に取得できます。
③ 中間テーブルを作成する
下記コマンドを実行して、中間テーブル用のマイグレーションファイルを作ります。
1 |
php artisan make:migration create_clubs_users_table --create=club_user |
マイグレーションファイルには、次のようにいれます。
【database/migrations/日付_create_clubs_users_table.php】
1 2 3 4 5 6 7 8 9 10 |
public function up() { Schema::create('club_user', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('club_id'); $table->unsignedBigInteger('user_id'); $table->string('note'); $table->timestamps(); }); } |
ファイルを保存後、php artisan migrate を実行します。
④ データを作っておく
各テーブルに、次のようにデータをいれておきましょう。
【usersテーブル】
【clubsテーブル】
【club_user中間テーブル】
本当はデータを保存するフォームを作成したりするほうが良いのですが、今回はとりあえず、データベースに直接入れちゃいます。
挿入タブをクリックし値をいれ、保存していきます。
なおデータベースを直接編集する以外に、tinkerを使ってデータを入れる手もあります。参考記事はこちら。
⑤ ビューファイルを作る
次に、ビューファイルを作成します。
今回はデフォルトである dashboard.blade.phpを使います。
ルート設定は下記のとおり。
【web.php】
1 2 3 |
Route::get('/dashboard', function () { return view('dashboard'); })->middleware(['auth'])->name('dashboard'); |
ビューファイルは次のようにいれます。
【dashboard.blade.php】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<x-app-layout> <x-slot name="header"> <h2 class="font-semibold text-xl text-gray-800 leading-tight"> {{ __('Dashboard') }} </h2> </x-slot> <div class="py-12"> <div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg"> <h1 class="mb-4 font-bold">{{auth()->user()->name}}さんが所属しているクラブ</h1> @foreach(auth()->user()->clubs as $club) <div class="mb-4"> <p>クラブ名:{{$club->name}}</p> <p>活動日:{{$club->day}}</p> <p>備考:{{$club->pivot->note}}</p> </div> @endforeach </div> </div> </div> </x-app-layout> |
上記は Breezeを使って作成しています。cssはTailwindを使っています。
ほかの環境でご利用になると、適切に表示されません。その場合、下記の部分だけ、お好きな場所に貼り付けて使ってくださいね。
1 2 3 4 5 6 7 8 9 |
<h1>{{auth()->user()->name}}さんが所属しているクラブ</h1> @foreach(auth()->user()->clubs as $club) <div class="mb-4"> <p>クラブ名:{{$club->name}}</p> <p>活動日:{{$club->day}}</p> <p>備考:{{$club->pivot->note}}</p> </div> @endforeach |
⑥ テストをする
最後にテストをします。
id番号が1のユーザーとしてログインした状態で、/dashboardにアクセスします。
すると、下記のように表示されます。
このように表示されていれば、テスト成功です!
⑦おまけ
ちなみに、ビューファイルでは pivot を使って中間テーブルの値を取り出しました。
【dashboard.blade.php】
1 |
<p>備考:{{$club->pivot->note}}</p> |
もしpivotではない名前にしたい時には、Userモデルのリレーションを設定した箇所に、asを追加します。たとえば、detailsという名前にするなら、下記のようにします。
【App\Models\User】
1 2 3 4 5 |
public function clubs() { return $this->belongsToMany('App\Models\Club') ->withPivot('note') ->as('details'); } |
こうすると、pivotではなく、detailsを使って、中間テーブルの値を取り出せます。
【dashboard.blade.php】
1 |
<p>備考:{{$club->details->note}}</p> |
さいごに
中間テーブル、今回ご紹介したwithPivotも使って、便利に活用していってくださいね。
中間テーブルの基本は、下記の記事で解説しています。
なお中間テーブルに複数の値を同時に保存する方法は、別記事にて解説しています。
今回の記事の続編のような内容です。よかったら併せて参考にしてくださいね。