[Laravel] BelongsToで1対多のリレーション

今回はLaravelで1対多のデータを扱ってみます。1対多はデータベースのリレーションではbelongsToということが多いですね。今回は複数のチームを登録するteamsテーブル、メンバーを登録するmembersテーブルを用意します。

メンバーはどれか一つのteamに所属します。1つのチーム側から見ると複数のメンバーが登録されることになり、1対多の関係になります。teamsテーブルが親、membersテーブルが子の関係になっています。

メンバーの新規登録、更新(編集)の時に所属チームを登録したり変更したりするCRUD(Create, Read, Update, Delete)を作成してみます。

ModelとMigrationの作成

MemberモデルとTeamモデルを作成します。マイグレーションファイルも同時に作成します。

[モデル]
プロジェクトディレクトリ/app/Member.php
プロジェクトディレクトリ/app/Team.php

[マイグレーション]
プロジェクトディレクトリ/database/migrations/2020_04_13_154956_create_members_table.php
プロジェクトディレクトリ/database/migrations/2020_04_13_155219_create_teams_table.php

の4つのファイルが作られます。

マイグレーションの実行

まず、モデル(テーブル)にカラムを設定し、MySQLにテーブルを作成しましょう。

「2020_04_13_154956_create_members_table.php」

$table->bigIncrements(‘id’);はデフォルトだと $table->(‘id’);になっています。このままだとリレーションがうまく設定されずエラーになりました。ここはbigIncrementsを付けるのを忘れないようにしましょう。この原因を見つけるまで時間がかかってしまいました。

Laravel5.8からは主キーのデフォルトがincrements()からbigIncrements()に変更になっています。
・INTの範囲は-2147483648〜2147483647[21億4千7百万までのデータ]
・BIGINTの範囲は-9223372036854775808~9223372036854775807[20桁までの数値]
大きな数値を使わない場合はINTのほうがパフォーマンスが良いのでINTの設定の方が良いです。(今回はテストなのでパフォーマンスは無視してBIGINT(bigIncrements)を使っています。

マイグレーションではBigIncrementで生成されたidはunSingledBigIntegerで指定(idに-値は使わない)

「020_04_13_155219_create_teams_table.php」

こちらも $table->bigIncrements(‘id’);のbigIncrementsを忘れずに!

2つのマイグレーションファイルが作り終わったらコンソールからマイグレーションを実行します。

「membersテーブル」
2020-04-15_00h27_05

「teamsテーブル」
2020-04-15_00h27_38

Temamsテーブルには「サッカー・野球」のようなデータをphpMyAdminで入力しておきます。

モデル

「/app/Member.php」(子)のファイルを編集します。

まずはお決まりの$fillableでカラムへのアクセスを許可します。

public function team(){}がリレーションの設定になります。
$this->belongsTo(‘/app/親モデル名’);と記載するだけでリレーションを作成してくれます。外部キーがteam_idという(小文字モデル名_id)になっている場合は、自動的にteam_idが外部キーとして処理されます。membersテーブルの中にteam_idを作成しておいたのは外部キーとして利用するためです。

「/app/Team.php」(親)

親の方も子と同様に$fillableを設定します。
こちらは1対多の多(親)になるので、hasMany()を使います。
$this->hasMany(‘App\Member’);と子モデルを設定します。
これで2つのリレーションの設定は終わりです。

ルーティング

routes/web.phpでルーティングを設定します。

この1行を記載するとCRUDに必要なルーティングが自動設定されます。
ルーティングを確認してみましょう。

2020-04-15_00h30_07

index()
create()
store()
show()
edit()
update()
destroy()
というルーティングが作られています。

コントローラーの作成

データベースの作成、モデルの作成、ルーティングの設定が終わったので、今度はコントローラを作っていきます。

「app/Http/Controllers/MemberController.php」の設定
コントローラー部分は長くなりますが、ひとつひとつのアクションの中身はシンプルです。

コントローラー全体

index()

「$members = Member::all();」では変数$membersに membersテーブルの全データを代入しています。
returnのところはデータをビューファイルに渡す設定です。
member/indexに$membersを渡しています。
compactは()の中に’members’と記載するだけで変数をビューに渡してくれる便利なメソッドです。

create()

情報の新規登録ではTeam名をセレクトできるようにします。セレクトボックスを作るのにTeamのデータが必要なのでTeamのデータを取得してmember/createに渡します。

store()

Member::create($request->all());は下記の2つを実行しています。
$request->all()で全データを連想配列で取得
Member::create()でmembersテーブルに新規データとして登録

「->with(‘success’, ‘登録完了’);」をつけて、登録完了の文字を登録させます。Laravelではこのように簡単にメッセージを表示させる仕組みが用意されています。

edit()

「$teams = Team::all();」
編集の時にはセレクトボックスでTeamの値を使うので取得しています。

「$member = Member::find($id);」
編集する個別のデータをidで抽出

2つのデータをビューに渡しています。

update()

$requestの中のname,team_idを$updateに代入。
「Member::where(‘id’, $id)->update($update);」でidを抽出し、そのidのデータを$updateのデータに上書きします。
「return back()->with(‘success’, ‘編集完了’);」は元のページに戻る、そして編集完了の文字を出力するという意味になります。

ビューファイル

index.blade.php

create.blade.php

edit.blade.php

リレーションの確認

裏側ではどのようなデータが動いているのか見てみます。
index.blade.phpに

を記載して「ドメイン名/member/index」にアクセスします。

長くなりますが、これが2件分のデーターです。Teamの内容が取得できていることがわかります。



Author: webmaster