理系公務員のプログラミング日記

【Laravel6】テーブルのリレーションと1対多の実装(ホテル予約システム3)

タグ:
Laravel
授業課題の解説

予約一覧画面を作成する

前回までで利用者に関する一覧表示(Read)と登録(Create)の機能が作成できました。

これと同じことをして、予約(Reserve)に関する一覧表示機能を作成しましょう。詳細は省略しますがこのような流れになります。

・マイグレーションを作成

php make:migrate CreateReservesTable

・シードでダミーデータを作成

php make:seeder ReservesTableSeeder

・Reserveモデルを作成

php make:model Reserve

・Reserveコントローラを作成

php make:Controller ReserveController

・予約一覧画面を(views/reserve/index.blade.php)に作成

予約一覧

利用者と予約の間のリレーションを設定する

ここからが本題です。予約一覧画面には予約した利用者のIDが表示されています。

利用者テーブルと予約テーブルの間にリレーションを定義して、この予約一覧画面で利用者テーブルに格納されている名前や住所などを表示してみます。

まず利用者と予約の間に成立する関係ですが、一人の利用者は複数回の予約をすることがあるので、一対多になります。

この関係のとき、利用者テーブルは主テーブル、予約テーブルは外部キーである利用者IDを持っているので、従テーブルとなります。

今回は従テーブルである予約テーブルとアクセスしており、追加で主テーブルの利用者テーブルの情報が欲しいので、予約テーブルのモデルであるReserveモデルbelongsToを設定します。

Reserve.php

<?php namespace App; use Illuminate\Database\Eloquent\Model; class Reserve extends Model { public function guest() { return $this->belongsTo('App\Guest'); } }

上記のコードは動作しない場合があります。

主キーとして、id以外を使っている場合や、外部キーの名前が主テーブルのモデル名_idになっていない場合などです。

Laravelが推奨するモデルや各キーの名前の付け方があり、その場合はLaravelが色々とサポートしてくれるのですが、そうでない場合は自身で主キーや外部キーを書いてあげる必要があります。

Reserve.php (主キーを指定する場合、belongsToの外部キー名や主テーブルの主キー名を指定する場合)

<?php namespace App; use Illuminate\Database\Eloquent\Model; class Reserve extends Model { // 主キーにid以外の名前を付けているなら指定する protected $primaryKey = 'reserve_id'; public function guest() { //belongsTo(主テーブルの指定、従テーブルの外部キー、対応する主テーブルの主キー) return $this->belongsTo('App\Guest','guest_id','guest_id'); } }

完全にLaravelの指定した名前の付け方に従う方が楽だと思いますが、個人的には主キー名もidではなくモデル名_idの方が理解しやすいと思うし、belongsToの指定も第3引数まで書いた方がわかりやすいと思うので、Laravelに任せずにしっかり全部書くのがオススメです。

リレーションを行うguest()メソッドを利用する

このguestメソッドは、Reserveモデルから呼び出すことでGuestモデルを取得できます。

そのため、下記のように書くことで、Guestモデルのデータを取得することができます。

@extends('layouts.hotel') @section('body') <table> <th>予約ID</th> <th>利用者ID</th> <th>お名前</th><th>ご住所</th><th>電話番号</th> <th>人数</th><th>チェックイン日</th><th>チェックアウト日</th> @foreach($items as $item) <tr> <th>{{$item->reserve_id}}</th> <th>{{$item->guest_id}}</th> <td>{{$item->guest->name}}</td> <td>{{$item->guest->address}}</td> <td>{{$item->guest->tel}}</td> <td>{{$item->number_of_reservations}}</td> <td>{{$item->check_in_day}}</td> <td>{{$item->check_out_day}}</td> @endforeach </table> @endsection

予約一覧