【Laravel8】多対多のリレーションを持つモデルを使ってリレーション先を取得する方法

今回は多対多のリレーションテーブルを作って、リレーション先のデータを取得するようにしてみます!

objectで取得できるものをarray(配列)でも取得してみようと思います!

中間テーブルの命名規則とかにもちょっとはまってしまった。。。

それでは行ってみよーー (oノ´3`)ノ ピューーン!!

参考
https://readouble.com/laravel/8.x/ja/eloquent-relationships.html

tableを作る

table概要

一旦こんな感じのテーブルを作ります↓

  • usersテーブル
idnameage
1山田17
2田中18
3中本17
4井出16
  • clubsテーブル
idname
1野球
2サッカー
3柔道
4バスケ

そして、上記のテーブルをつなぐ中間テーブルを作成します。

  • club_userテーブル
iduser_idclub_id
111
212
322
443

説明をすると、userは複数のclubに所属できるようになっています。
clubは複数のuserを所属させることができます。

これが多対多のリレーションになっています。

ほい、ではここからテーブルを作っていきましょう

tableの作成

table作成コマンド

※中間テーブルを作成するときの命名規則にも注意してください。

//table作成時table名は複数系にする必要がある。 例) create_user_tableはダメ× php artisan make:migration create_users_table php artisan make:migration create_clubs_table //中間テーブルは対象のテーブルを単数形にして作成。 今回の場合はclubsテーブルとusersテーブルを合わせてclub_user //tableの順番はアルファベット順 clubのc userのu で考える php artisan make:migration create_club_user_table
Code language: JavaScript (javascript)

usersテーブルとclubsテーブルの作り方はここではスキップ

database/migrations/yyyy_mm_dd_xxxxxx_create_club_user_table

<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateClubUserTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('club_user', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('user_id')->comment('ユーザーID'); $table->unsignedBigInteger('club_id')->comment('クラブID'); //外部キー $table->foreign('user_id')->references('id')->on('users')->onUpdate('cascade')->onDelete('cascade')->comment(''); $table->foreign('club_id')->references('id')->on('clubs')->onUpdate('cascade')->onDelete('cascade')->comment(''); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('club_user'); } }
Code language: HTML, XML (xml)

Modelにリレーションの設定

多対多のリレーションしますよーっていうのをModelに書きます。

使うのはBelongsToManyです。

↓参考
https://readouble.com/laravel/8.x/ja/eloquent-relationships.html#many-to-many

もしModelが作成されていなかったら以下コマンド

//model名はアッパーキャメル記法で書く ex. User, TestUser php artisan make:model {Model名
Code language: JavaScript (javascript)

app/Models/User.php

//追加↓ public function clubs() { return $this->belongsToMany(Club::class); }
Code language: PHP (php)

app/Models/Club.php

//追加↓ public function users() { return $this->belongsToMany(User::class); }
Code language: PHP (php)

はい!これで準備は完了!

リレーション先の取得

とりあえずリレーション先を取得しようと思いますが、データが入ってない…

今回は面倒なのでとりあえずseeder使ってダミーデータ入れることにしまス。

seederの使い方は以下からどうぞ

https://yama-weblog.com/create-dummy-data-using-seeder-in-laravel8/

ほい、そしたら取得していきましょう。

データは最初に確認したtableのデータが入っているとしましょう。

そして以下のようにして対象ユーザが所属するクラブを取得してみました。

ほかにも取得方法はいろいろあるので試してみましょう!

//Requestではuserのidを投げている。 //pluck('name')= clubsテーブルのnameカラムを指定して取得。 //toArray() = オブジェクトとして帰ってくるので配列にして返すようにする。 $clubs = User::find($request->id)->clubs()->pluck('name')->toArray(); return $clubs;
Code language: PHP (php)

その他の取得方法

すべてのリレーションはクエリビルダとしても機能するため、rolesメソッドを呼び出し、クエリに条件をチェーンによりつなげることで、リレーションのクエリへさらに制約を追加できます。

$roles = User::find(1)->roles()->orderBy(‘name’)->get();

公式より https://readouble.com/laravel/8.x/ja/eloquent-relationships.html#many-to-many

はい、こんな感じでいろいろやり方はありますね~

まとめ

今回少し時間がかかったところは、

  • 多対多の中間テーブルの命名規則を無視した書き方をしていてエラーで困っていた。
  • objectでは取得できたけど、配列でデータを取得方法につまった。

以上2点にすこし時間がかかりました。

コメントを残す

メールアドレスが公開されることはありません。

CAPTCHA