E120 ユーザー予約一覧とキャンセル機能の実装

今回はユーザー予約一覧とキャンセルを行うための機能の実装方法を紹介します。

ユーザー予約一覧とキャンセル機能作成

①ユーザーの予約一覧のコントローラーを作成する。

$sail artisan make:controller ReserveController

※下記の様に表示されれば成功です。

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

②ルーティングを追加する。

※下記、L43を参照

routes/web.php
  Route::middleware('auth')->group(function () {
      // プロフィールページ
      Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
      Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
      Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
  
      // カレンダーページ
      Route::get('/calendar', [EventController::class, 'index'])->name('event.index');
      //Route::post('/schedule-get', [EventController::class, 'getSchedules'])->name('schedule-get');
      Route::get('/events', [EventController::class, 'getEvents'])->name('event.get');
      Route::post('/reserve-add', [EventController::class, 'addReserve'])->name('reserve.add');
  
      // 予約ページ
+     Route::resource('reserve', ReserveController::class)->only(['index', 'destroy']);
  }); 

③コントローラーに表示、削除処理を実装する。

※下記、参照し上書きする

app/Http/Controllers/ReserveController.php
<?php

  namespace App\Http\Controllers;
  
  use App\Mail\ReserveCanceled;
  use App\Models\Reserve;
  use Illuminate\Support\Facades\Auth;
  use Illuminate\Support\Facades\Mail;
  use Illuminate\Support\Facades\Log;
  
  class ReserveController extends Controller
  {
      /**
       * Display a listing of the resource.
       *
       * @return \Illuminate\View\View
       */
      public function index()
      {
          $reserves = Reserve::where('user_id', Auth::id())->orderBy('id')->get();
          return view('reserve.index', compact('reserves'));
      }
  
      /**
       * Remove the specified resource from storage.
       *
       * @param  \App\Models\Reserve  $reserve
       * @return \Illuminate\Http\RedirectResponse
       */
      public function destroy(reserve $reserve)
      {
          $reserve->delete();
  
          Log::info("[delete reserve] " . $reserve->id);
  
          // 予約キャンセルメールを送信
          Mail::to($reserve->user->email)->send(new ReserveCanceled($reserve));
  
          return redirect()->route('reserve.index')->with('message', 'reserve canceld!');
      }
}

④キャンセル時にユーザーに予約キャンセルメールを送信する。

送信メールのクラスを作成します。

$sail artisan make:mail ReserveCanceled

※下記の様に表示されたら成功。

$INFO  Mailable [app/Mail/ReserveCanceled.php] created successfully. 

※下記、参照し修正する

app/Mail/ReserveCanceled.php
  <?php
  
  namespace App\Mail;
  
+  use App\Models\Reserve;
   use Illuminate\Bus\Queueable;
   use Illuminate\Contracts\Queue\ShouldQueue;
   use Illuminate\Mail\Mailable;
   use Illuminate\Mail\Mailables\Content;
   use Illuminate\Mail\Mailables\Envelope;
+  use Illuminate\Mail\Mailables\Address;
   use Illuminate\Queue\SerializesModels;
  
   class ReserveCanceled extends Mailable
   {
-      use Queueable, SerializesModels;
+      use Queueable;
+      use SerializesModels;
+  
+      public $reserve;
  
       /**
        * Create a new message instance.
+       *
+       * @return void
        */
-      public function __construct()
+      public function __construct(Reserve $reserve)
       {
-          //
+          $this->reserve = $reserve;
       }
  
       /**
        * Get the message envelope.
+      *
+      * @return \Illuminate\Mail\Mailables\Envelope
        */
-      public function envelope(): Envelope
+      public function envelope()
       {
           return new Envelope(
-              subject: 'Reserve Canceled',
+              from: new Address('no-reply@example.com', '簡易予約アプリ'),
+              subject: '予約をキャンセルしました',
           );
       }
  
       /**
        * Get the message content definition.
+       *
+       * @return \Illuminate\Mail\Mailables\Content
        */
-      public function content(): Content
+      public function content()
       {
           return new Content(
-              view: 'view.name',
+              view: 'emails.reserve-canceled',
           );
       }
  
       /**
        * Get the attachments for the message.
        *
-       * @return array<int, \Illuminate\Mail\Mailables\Attachment>
+       * @return array
        */
-      public function attachments(): array
+      public function attachments()
       {
           return [];
       }
-  }
+  }

⑤送信メールのテンプレートファイルを作成する。

resources/views/emails/reserve-canceled.blade.php を新規作成し、メール送信処理をReserveControllerに実装する。

resources/views/emails/reserve-canceled.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
</head>
<body>
    <h1>
        スケジュール予約をキャンセルしました。
    </h1>
    <p>
        {{ $reserve->user->name }}
    </p>
    <p>
        スケジュール予約がキャンセルされました。
    </p>
    <p>
        予約番号:{{ $reserve->id }} <br>
        タイトル:{{ $reserve->schedule->title }} <br>
        日時:{{ $reserve->schedule->from_date }}{{ $reserve->schedule->due_date }} <br>
        スタッフ:{{ $reserve->schedule->staff_name }}
    </p>

</body>
</html>

※下記、参照し上書きする。

app/Http/Controllers/ReserveController.php
<?php

namespace App\Http\Controllers;

use App\Mail\ReserveCanceled;
use App\Models\Reserve;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Log;

class ReserveController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\View\View
     */
    public function index()
    {
        $reserves = Reserve::where('user_id', Auth::id())->orderBy('id')->get();
        return view('reserve.index', compact('reserves'));
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Reserve  $reserve
     * @return \Illuminate\Http\RedirectResponse
     */
    public function destroy(reserve $reserve)
    {
        $reserve->delete();

        Log::info("[delete reserve] " . $reserve->id);

        // 予約キャンセルメールを送信
        Mail::to($reserve->user->email)->send(new ReserveCanceled($reserve));

        return redirect()->route('reserve.index')->with('message', 'reserve canceld!');
    }
}

確認事項

登録済みユーザーでログインし、/reserve にアクセスして予約済みの予約一覧が表示されるかを確認する。

予約一覧でキャンセルを実施して、予約がキャンセルできるかを確認する。

キャンセル時、ユーザーのメールアドレス宛にキャンセル完了メールが送信されるかを確認する。

管理画面 予約管理でキャンセルした予約が消えるかを確認する。

※本記事までの内容ができていれば、サンプルアプリの機能の実装が完了しておりますので一連の機能を操作してみましょう。

---