見出し画像

LaravelでCRUDシステムを構築する①

 下記の記事で作った素のPHPによるユーザー管理のCRUDシステムをLaravelで作り直します。フレームワークを使用することにより、フレームワークの提供する独自のメソッドや関数、コマンド等を覚える必要がありますが、短いコードで素早く開発することが可能になります。

筆者の開発環境

PC:Apple M1 チップ搭載MacBook Air
OS:macOS Sonoma 14.1(23B74)
MAMP:6.8
PHP:8.2.0
Laravel:10.29.0

Laravelのインストール

Laravelのインストールは下記の記事を参考に済ませておいてください。

データベースの作成

 データベースの作成がまだの場合はphpMyAdminで作成しておきましょう。MAMPのコントロールパネルの右上にある「WebStart」ボタンをクリックしてください。

MAMPコントロールパネル

 ブラウザに下記のページが開きますので「Tools」から「phpMyAdmin」をクリックしてください。

WebStartページ

phpMyAdminが起動します。「新規作成」をクリックしてください。

phpMyAdmin

 「データベース名」の項目に「laravel_crud」と入力し、その右隣のプルダウンから「utf8mb4_general_ci」を選択し「作成」ボタンをクリックしてください。

phpMyAdmin

 下記のように左サイドのデータベース一覧に「laravel_crud」が追加されれば成功です。phpMyAdminページはこの後も使いますので閉じずにそのままにしておいてください。

phpMyAdmin

 Laravelのデータベース接続設定を編集します。お使いのエディターでプロジェクトを開き.envというファイルを下記のように編集してください。下記設定はMAMPのデフォルト設定の場合です。

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=

↓

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=8889
DB_DATABASE=laravel_crud
DB_USERNAME=root
DB_PASSWORD=root

!!!注意!!!
本番環境ではrootユーザーの使用、推測可能なパスワードの使用は絶対に行わないでください!

 設定が正しくできたか、下記のコマンドを実行して確かめましょう。ターミナルを起動しプロジェクトフォルダで実行してください。デフォルトのマイグレーションファイルからテーブルが作られます。

php artisan migrate

下記のように表示されれば成功です。

   INFO  Preparing database.  

  Creating migration table .................................................................................................... 17ms DONE

   INFO  Running migrations.  

  2014_10_12_000000_create_users_table ........................................................................................ 22ms DONE
  2014_10_12_100000_create_password_reset_tokens_table ........................................................................ 23ms DONE
  2019_08_19_000000_create_failed_jobs_table .................................................................................. 20ms DONE
  2019_12_14_000001_create_personal_access_tokens_table ....................................................................... 28ms DONE

 念のためphpMyAdminでも確認してみましょう。左サイドのデータベース一覧から「laravel_crud」をクリックし、下記のように5つのテーブルが作られていることを確認してください。

php MyAdmin

 このようにLaravelではマイグレーションという仕組みを使って、テーブルの作成やカラムの追加/削除等をコードとコマンドで行います。

Memberモデルの作成

 実はLaravelにはデフォルトでUserモデルとusersテーブルが存在します。そこで今回はユーザーの代わりにメンバー管理のCRUDシステムを作成することとします。
 Laravelではモデルを作成するのに専用のコマンドを使用します。そこにオプションを渡すことで関連ファイルを一気に生成することが可能です。下記のコマンドを実行してください。

php artisan make:model Member -mcrR

成功すれば下記のように表示されます。

   INFO  Model [app/Models/Member.php] created successfully.  

   INFO  Migration [database/migrations/2023_10_28_115202_create_members_table.php] created successfully.  

   INFO  Request [app/Http/Requests/StoreMemberRequest.php] created successfully.  

   INFO  Request [app/Http/Requests/UpdateMemberRequest.php] created successfully.  

   INFO  Controller [app/Http/Controllers/MemberController.php] created successfully.  

今回はモデルファイルの他に、

  • membersテーブルを作成するマイグレーションファイル

  • バリデーション等を設定するフォームリクエストファイル

  • CRUD用のメソッドがすでに準備されたコントローラーファイル

が生成されました。

マイグレーションファイルの編集

 「database/migrations/2023_10_28_115202_create_members_table.php」をエディターで開いてください。ファイル名の先頭の「2023_10_28_115202」は作成日時ですので、ファイル名が異なると思いますので「create_members_table」というファイル名で探してください。
 下記のように編集してください。nameとemailという2つのカラムを持つmembersテーブルを作成します。

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('members', function (Blueprint $table) {
            $table->id();
            $table->string('name', 50);
            $table->string('email', 100);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('members');
    }
};

編集できたら下記のコマンドを実行してください。

php artisan migrate

下記のように表示されれば成功です。

   INFO  Running migrations.  

  2023_10_28_115202_create_members_table ...................................................................................... 13ms DONE

 phpMyAdminでも確認してみましょう。左サイドのデータベース一覧から「laravel_crud」をクリックし、テーブル一覧に「members」が追加されていることを確認してください。

phpMyAdmin

 カラムの確認もしてみましょう。「members」テーブルをクリックし、上部のメニューから「構造」をクリックしてください。下記のようにnameとemailが作成されていれば成功です。

phpMyAdmin

Memberモデルの編集

 「app/Models/Member.php」を下記のように編集してください。$fillableというプロパティはここに指定されたカラム名のみが作成時や更新時に有効になるようにします。逆に言えば、ここに指定されていないカラム名は無視されるということになります。マスアサインメントという脆弱性の対策です。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Member extends Model
{
    use HasFactory;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
    ];
}

ルーティングの設定

 「routes/web.php」というルーティング設定用のファイルを下記のように編集してください。「Route::resource('member', MemberController::class);」という1行を設定するだけでCRUD用のメソッドが自動で生成されます。MemberControllerをuseするのを忘れないようにしてください。

<?php

use App\Http\Controllers\MemberController;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "web" middleware group. Make something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::resource('member', MemberController::class);

 編集できたら生成されるルーティングを確認してみましょう。下記のコマンドを実行してください。

php artisan route:list --path=member

下記のように表示されます。

  GET|HEAD        member .......................................................................... member.index › MemberController@index
  POST            member .......................................................................... member.store › MemberController@store
  GET|HEAD        member/create ................................................................. member.create › MemberController@create
  GET|HEAD        member/{member} ................................................................... member.show › MemberController@show
  PUT|PATCH       member/{member} ............................................................... member.update › MemberController@update
  DELETE          member/{member} ............................................................. member.destroy › MemberController@destroy
  GET|HEAD        member/{member}/edit .............................................................. member.edit › MemberController@edit

上から順に

  • 一覧画面

  • 新規登録処理

  • 登録フォームの表示

  • 詳細画面

  • 更新処理

  • 削除処理

  • 編集フォームの表示

となっており、それぞれのURLに対応するコントローラー名とメソッド名が明示されています。「member.index」や「member.create」というのはURLの別名(エイリアス)定義です。後ほど出てくるroute()関数に「member.index」というエイリアスを渡すと「http://localhost:8888/member」というURLを生成してくれます。

レイアウトの構築

 各画面の共通パーツはコンポーネントという仕組みを使いレイアウトにまとめます。下記のコマンドを実行しコンポーネントファイルを格納するフォルダを作成してください。

mkdir resources/views/components

 下記のコマンドを実行しレイアウト用のビューファイルを作成してください。

touch resources/views/components/layout.blade.php

 layout.blade.phpを下記のように編集してください。画面のデザインにBootstrap5を使用しますのでCDNから読み込んでいます。フラッシュメッセージの表示パーツもすでに作っておきます。

<!doctype html>
<html lang="ja">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>{{ $title ?? 'メンバー管理' }}</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
</head>

<body>
    <div class="container">
        <div class="row">
            <div class="col">
                @if (session()->has('success'))
                    <div class="alert alert-success mt-5" role="alert">
                        {{ session()->get('success') }}
                    </div>
                @endif

                {{ $slot }}
            </div>
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
</body>

</html>

メンバー登録フォームの作成

 それでは準備が整いましたのでCRUD処理を作成していきます。まずは登録処理を作成します。ユーザーの入力値をサーバーにPOSTするフォームから作成していきます。

MemberControllerの編集

 createメソッドを下記のように編集してください。ビューファイルを返します。

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        return view('member.create');
    }

ビューファイルの作成

 下記のコマンドを実行しメンバー管理用のビューファイルを格納するフォルダを作成してください。

mkdir resources/views/member

下記のコマンドを実行しcreate.blade.phpを作成してください。

touch resources/views/member/create.blade.php

 create.blade.phpを下記のように編集してください。CSRF対策として「@csrf」を必ず埋め込んでください。バリデーションエラー時にはエラーメッセージを表示し、old()関数によって直前の入力値を表示していることにも注目してください。

<x-layout>
    <x-slot:title>
        新規登録 | メンバー管理
    </x-slot>

    <form action="{{ route('member.store') }}" method="POST" class="mt-5 @if($errors->isNotEmpty()) was-validated @endif" novalidate>
        @csrf
        <div class="mb-3">
            <label for="name" class="form-label">名前</label>
            <input type="text" id="name" class="form-control" name="name" maxlength="50" value="{{ old('name') }}" required>
            @error('name')
                <div class="invalid-feedback">{{ $message }}</div>
            @enderror
        </div>
        <div class="mb-3">
            <label for="email" class="form-label">メールアドレス</label>
            <input type="text" id="name" class="form-control" name="email" maxlength="100" value="{{ old('email') }}" required>
            @error('email')
                <div class="invalid-feedback">{{ $message }}</div>
            @enderror
        </div>
        <button type="submit" class="btn btn-primary">登録</button>
    </form>
</x-layout>

画面イメージは下記の通りです。

登録フォーム

メンバー登録処理の作成

MemberControllerの編集

 storeメソッドを下記のように編集してください。データベースへ登録し、登録フォームへリダイレクトしています。リダイレクトの直前にフラッシュメッセージの登録も行っています。

    /**
     * Store a newly created resource in storage.
     */
    public function store(StoreMemberRequest $request)
    {
        Member::create($request->only(['name', 'email']));

        return redirect()->route('member.create')->with('success', 'メンバーの登録に成功しました。');
    }

フォームリクエストの編集

 バリデーションを設定します。「app/Http/Requests/StoreMemberRequest.php」を下記のように編集してください。rules()メソッドに各カラムのバリデーションルールを定義しています。今回は必須項目をチェックする「required」ルールだけ設定します。
 authorize()メソッドがtrueを返すようにしてください。attributes()メソッドとmessages()メソッドをそれぞれ追加してください。

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreMemberRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        return [
            'name' => 'required',
            'email' => 'required',
        ];
    }

    /**
     * カラム名を日本語化
     *
     * @return array
     */
    public function attributes(): array
    {
        return [
            'name' => '名前',
            'email' => 'メールアドレス',
        ];
    }

    /**
     * エラーメッセージ
     *
     * @return array
     */
    public function messages(): array
    {
        return [
            'name.required' => ':attributeを入力してください。',
            'email.required' => ':attributeを入力してください。',
        ];
    }
}

動作確認

 編集できたらhttp://localhost:8888/member/createにアクセスしてください。名前とメールアドレスを入力し、正常に登録されることを確認してください。下記のようにフラッシュメッセージが表示されれば成功です。

登録フォーム

 phpMyAdminでも確認してみましょう。上部のメニューから「表示」をクリックしてください。下記のようにデータが登録されていればOKです。

phpMyAdmin

 バリデーションエラーも試してみましょう。何も入力せずに登録ボタンをクリックしてください。下記のようにエラーメッセージが表示されればOKです。

バリデーションエラー

 old()関数が働いて直前の入力値を表示できることも試しておきましょう。名前のみ入力して登録ボタンをクリックしてください。下記のように入力した値が保持されていればOKです。メールアドレスのみ入力のパターンも試せれば尚良いです。

入力値の保持

テストが終わったら、もう何件かデータを登録しておきましょう。

メンバー一覧画面の作成

MemberControllerの編集

 indexメソッドを下記のように編集してください。登録の新しい順番にメンバーリストを取得しています。viewメソッドの第2引数に配列を渡すことでビューファイルに変数を渡すことができます。

    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        $members = Member::orderBy('id', 'DESC')->get();

        return view('member.index', compact('members'));
    }

一覧画面の作成

下記のコマンドを実行してください。

touch resources/views/member/index.blade.php

 index.phpを下記のように編集してください。$members配列をforeachで1件ずつ取り出しテーブルに表示しています。ユーザーによって入力された値を表示する時は必ず「{{ }}」で囲んで表示してください!Laravelにおけるクロスサイトスクリプティング(XSS)攻撃へのセキュリティ対策です。

<x-layout>
    <x-slot:title>
        一覧 | メンバー管理
    </x-slot>

    <a href="{{ route('member.create') }}" class="btn btn-success mt-5">新規登録</a>
    <table class="table table-bordered mt-5">
        <thead>
            <tr>
                <th>ID</th>
                <th>名前</th>
                <th>メールアドレス</th>
            </tr>
        </thead>
        <tbody>
            @foreach ($members as $member)
                <tr>
                    <td>{{ $member->id }}</td>
                    <td>{{ $member->name }}</td>
                    <td>{{ $member->email }}</td>
                </tr>
            @endforeach
        </tbody>
    </table>
</x-layout>

 編集できたらhttp://localhost:8888/memberにアクセスしてください。先ほど登録したデータが一覧で表示されれば成功です。

一覧画面

リダイレクト先の変更

 新規登録後のリダイレクト先を一覧画面に修正しましょう。MemberControllerのstoreメソッドを下記のように編集してください。

    /**
     * Store a newly created resource in storage.
     */
    public function store(StoreMemberRequest $request)
    {
        Member::create($request->only(['name', 'email']));

        return redirect()->route('member.index')->with('success', 'メンバーの登録に成功しました。');
    }

 編集できたらhttp://localhost:8888/member/createにアクセスするか、新規登録ボタンをクリックしてください。データを入力し下記のようにリダイレクトされれば成功です。

一覧画面

 新規登録フォームに一覧画面へ「戻る」ボタンをつけましょう。resources/views/member/create.blade.phpを下記のように修正してください。

<x-layout>
    (省略)

    <a href="{{ route('member.index') }}" class="btn btn-secondary mt-5">戻る</a>
    <form action="{{ route('member.store') }}" method="POST" class="mt-5 @if($errors->isNotEmpty()) was-validated @endif" novalidate>
        (省略)
    </form>
</x-layout>
 新規登録フォーム

メンバー編集フォームの作成

MemberControllerの編集

 editメソッドを下記のように編集してください。メソッドインジェクションという仕組みにより、URLで指定されたmemberのidから自動的にmemberインスタンスが取得されます。

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(Member $member)
    {
        return view('member.edit', compact('member'));
    }

ビューファイルの作成

下記のコマンドを実行しedit.blade.phpを作成してください。

touch resources/views/member/edit.blade.php

 edit.blade.phpを下記のように編集してください。route()関数の第2引数にmemberインスタンスを渡すとURLパラメーターにidをセットすることができます。formはPATCHメソッドをサポートしていないのですが「@method('PATCH')」とすることで擬似的にPATCHメソッドを表現できます。old()関数の第2引数に、oldの値がnullだった場合のデフォルト値を設定できます。ここではデータベースから取得した値をデフォルト値として渡しています。

<x-layout>
    <x-slot:title>
        編集 | メンバー管理
    </x-slot>

    <a href="{{ route('member.index') }}" class="btn btn-secondary mt-5">戻る</a>
    <form action="{{ route('member.update', $member) }}" method="POST" class="mt-5 @if($errors->isNotEmpty()) was-validated @endif" novalidate>
        @csrf
        @method('PATCH')
        <div class="mb-3">
            <label for="name" class="form-label">名前</label>
            <input type="text" id="name" class="form-control" name="name" maxlength="50" value="{{ old('name', $member->name) }}" required>
            @error('name')
                <div class="invalid-feedback">{{ $message }}</div>
            @enderror
        </div>
        <div class="mb-3">
            <label for="email" class="form-label">メールアドレス</label>
            <input type="text" id="name" class="form-control" name="email" maxlength="100" value="{{ old('email', $member->email) }}" required>
            @error('email')
                <div class="invalid-feedback">{{ $message }}</div>
            @enderror
        </div>
        <button type="submit" class="btn btn-primary">更新</button>
    </form>
</x-layout>

 resources/views/member/index.blade.phpを下記のように編集してください。編集画面へのリンクを設置します。

<x-layout>
    (省略)

    <table class="table table-bordered mt-5">
        <thead>
            <tr>
                <th>ID</th>
                <th>名前</th>
                <th>メールアドレス</th>
                <th>編集</th>
            </tr>
        </thead>
        <tbody>
            @foreach ($members as $member)
                <tr>
                    <td>{{ $member->id }}</td>
                    <td>{{ $member->name }}</td>
                    <td>{{ $member->email }}</td>
                    <td>
                        <a href="{{ route('member.edit', $member) }}" class="btn btn-primary">編集</a>
                    </td>
                </tr>
            @endforeach
        </tbody>
    </table>
</x-layout>
一覧画面

メンバー更新処理の作成

MemberControlllerの編集

 updateメソッドを下記のように編集してください。all()メソッドはPOSTされた値を配列で返します。fill()メソッドは$fillableで指定したカラムのみを更新対象に設定します。

    /**
     * Update the specified resource in storage.
     */
    public function update(UpdateMemberRequest $request, Member $member)
    {
        $member->fill($request->all())->save();

        return redirect()->route('member.index')->with('success', 'メンバーの更新に成功しました。');
    }

フォームリクエストの編集

 バリデーションを設定します。「app/Http/Requests/UpdateMemberRequest.php」を下記のように編集してください。rules()メソッドに各カラムのバリデーションルールを定義しています。今回は必須項目をチェックする「required」ルールだけ設定します。
 authorize()メソッドがtrueを返すようにしてください。attributes()メソッドとmessages()メソッドをそれぞれ追加してください。

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class UpdateMemberRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        return [
            'name' => 'required',
            'email' => 'required',
        ];
    }

    /**
     * カラム名を日本語化
     *
     * @return array
     */
    public function attributes(): array
    {
        return [
            'name' => '名前',
            'email' => 'メールアドレス',
        ];
    }

    /**
     * エラーメッセージ
     *
     * @return array
     */
    public function messages(): array
    {
        return [
            'name.required' => ':attributeを入力してください。',
            'email.required' => ':attributeを入力してください。',
        ];
    }
}

動作確認

 編集できたら一覧画面(http://localhost:8888/member/create)から編集フォームにアクセスしてください。データを修正してデータが更新されること確認してください。下記のようにフラッシュメッセージが表示されれば成功です。

更新処理

 バリデーションエラーも確認しましょう。名前を空にして更新ボタンをクリックしてください。下記のようにエラーメッセージが表示されればOKです。メールアドレスも同様に検査できれば尚良いです。

バリデーションエラー

メンバー削除処理の作成

MemberControllerの編集

destroyメソッドを下記のように編集してください。

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(Member $member)
    {
        $member->delete();

        return redirect()->route('member.index')->with('success', 'メンバーの削除に成功しました。');
    }

削除フォームの作成

 resources/views/member/index.blade.phpを下記のように編集してください。

<x-layout>
    (省略)

    <table class="table table-bordered mt-5">
        <thead>
            <tr>
                <th>ID</th>
                <th>名前</th>
                <th>メールアドレス</th>
                <th>編集</th>
                <th>削除</th>
            </tr>
        </thead>
        <tbody>
            @foreach ($members as $member)
                <tr>
                    <td>{{ $member->id }}</td>
                    <td>{{ $member->name }}</td>
                    <td>{{ $member->email }}</td>
                    <td>
                        <a href="{{ route('member.edit', $member) }}" class="btn btn-primary">編集</a>
                    </td>
                    <td>
                        <form action="{{ route('member.destroy', $member) }}" method="POST">
                            @csrf
                            @method('DELETE')
                            <button class="btn btn-danger">削除</button>
                        </form>
                    </td>
                </tr>
            @endforeach
        </tbody>
    </table>
</x-layout>

動作確認

 編集できたら一覧画面(http://localhost:8888/member/create)から削除ボタンをクリックしてください。データが削除されること確認してください。下記のようにフラッシュメッセージが表示されれば成功です。

削除処理

メンバー詳細画面の作成

MemberControllerの編集

showメソッドを下記のように編集してください。

    /**
     * Display the specified resource.
     */
    public function show(Member $member)
    {
        return view('member.show', compact('member'));
    }

ビューファイルの作成

下記のコマンドを実行しshow.blade.phpを作成してください。

touch resources/views/member/show.blade.php

show.blade.phpを下記のように編集してください。

<x-layout>
    <x-slot:title>
        詳細 | メンバー管理
    </x-slot>

    <a href="{{ route('member.index') }}" class="btn btn-secondary mt-5">戻る</a>
    <p class="mt-5">ID: {{ $member->id }}</p>
    <p>名前: {{ $member->name }}</p>
    <p>メールアドレス: {{ $member->email }}</p>
    <p>作成日時: {{ $member->created_at }}</p>
    <p>更新日時: {{ $member->updated_at }}</p>
</x-layout>

 一覧画面の名前をリンカブルに修正します。resources/views/member/index.blade.phpを下記のように修正してください。

<x-layout>
    (省略)

    <table class="table table-bordered mt-5">
        <thead>
            <tr>
                <th>ID</th>
                <th>名前</th>
                <th>メールアドレス</th>
                <th>編集</th>
                <th>削除</th>
            </tr>
        </thead>
        <tbody>
            @foreach ($members as $member)
                <tr>
                    <td>{{ $member->id }}</td>
                    <td>
                        <a href="{{ route('member.show', $member) }}">{{ $member->name }}</a>
                    </td>
                    <td>{{ $member->email }}</td>
                    <td>
                        <a href="{{ route('member.edit', $member) }}" class="btn btn-primary">編集</a>
                    </td>
                    <td>
                        <form action="{{ route('member.destroy', $member) }}" method="POST">
                            @csrf
                            @method('DELETE')
                            <button class="btn btn-danger">削除</button>
                        </form>
                    </td>
                </tr>
            @endforeach
        </tbody>
    </table>
</x-layout>

動作確認

 編集できたら一覧画面(http://localhost:8888/member)にアクセスし、名前をクリックして詳細画面が表示されることを確認してください。下記のように表示されれば成功です。

詳細画面

404画面の表示

 存在しないmemberのID等が渡された時にオリジナルの404ページを表示します。

ビューファイルの作成

 下記のコマンドを実行しエラー画面用のビューファイルを格納するフォルダを作成してください。

mkdir resources/views/errors

下記のコマンドを実行し404.blade.phpを作成してください。

touch resources/views/errors/404.blade.php

404.blade.phpを下記のように編集してください。

<x-layout>
    <x-slot:title>
        404 Not Found
    </x-slot>

    <h1 class="mt-5">404 Not Found</h1>
    <a href="{{ route('member.index') }}">メンバーリストへ戻る</a>
</x-layout>

動作確認

 http://localhost:8888/member/100にアクセスしてください。idの「100」は存在しないidであれば何でもかまいません。下記のように表示されれば成功です。

404ページ

 解説は以上です。次回はこのCRUDシステムのテストコードを実装します。おつかれさまでした。

PHP/Laravelのシステム開発は株式会社パパグラムへぜひご相談ください。


この記事が気に入ったらサポートをしてみませんか?