This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

More than 1 year has passed since last update.

Laravel応用教材②

Last updated at Posted at 2022-07-01

プロジェクト作成

プロジェクト一覧画面にあった、追加ボタンからプロジェクトを追加できるようにしていきましょう。

ルーティング

まずはルーティングから行っていきます。
task-app/routes/web.phpを下記の通り編集してください。

web.php
<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ProjectController;
use App\Http\Controllers\TaskController;

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

Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(['auth'])->name('dashboard');

// ログイン必須ルート
Route::middleware('auth')->group(function () {
    // プロジェクト一覧画面
    Route::get('projects', [ProjectController::class, 'index'])->name('projects.index');

    // プロジェクト作成画面
    Route::get('project/create', [ProjectController::class, 'create'])->name('projects.create'); // ここを追加

    // プロジェクト作成処理
    Route::post('project/store', [ProjectController::class, 'store'])->name('projects.store'); // ここを追加

    // タスク一覧画面
    Route::get('projects/{id}/tasks', [TaskController::class, 'index'])->name('tasks.index');
});

require __DIR__.'/auth.php';

2つのルートを追加しています。
1つ目がプロジェクト作成画面を表示させるためのcreateメソッドに処理を渡すルートで、2つ目はプロジェクト作成処理をさせるstoreメソッドに処理を渡すルートです。

プロジェクト作成画面表示

それではプロジェクト作成画面を表示させる処理やビューを作成していきましょう。

コントローラー編集

まずはルートで定義したプロジェクト作成画面を表示させるcreateメソッドを作成していきましょう。

task-app/app/Http/Controllers/ProjectController.phpを下記の通り編集してください。

ProjectController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class ProjectController extends Controller
{
    /**
     * プロジェクト一覧画面
     */
    public function index()
    {
        // ログインユーザーが作成した全てのプロジェクトを取得
        $projects = Auth::user()->projects->all();

        return view('projects.index', compact('projects'));
    }

    /**
     * プロジェクト作成画面
     */
    public function create()
    {
        return view('projects.create');
    }
}

createメソッドが実行されるとprojects/create.blade.phpが表示されるように処理を記述しました。

ビュー作成&編集

http://localhost/project/createにアクセスがあった場合、Projectコントローラーprojects/create.blade.phpを表示させるように処理を記述したので、create.blade.phpを作成していきましょう。

task-app/resources/views/projectsディレクトリ配下にcreate.blade.phpを作成してください。
コマンドで作成する場合は、ターミナルで下記コマンドをtask-appディレクトリ上で実行してください。

コマンド
$ touch resources/views/projects/create.blade.php

作成したtask-app/resources/views/projects/create.blade.phpを下記の通り編集してください。

resources/views/projects/create.blade.php
@extends('layouts.layout')

@section('title')
    プロジェクト作成
@endsection

@section('content')
    <div class="container mt-4">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header text-center">プロジェクト作成</div>
     
                    <div class="card-body">
                        <form method="POST" action="{{ route('projects.store') }}">
                            @csrf
     
                            <div class="form-group d-flex flex-column flex-md-row">
                                <label for="project_name" class="col-md-4 col-form-label text-md-right">プロジェクト名:</label>
                                <div class="col-md-6">
                                    <input id="project_name" type="type" class="form-control @error('project_name') is-invalid @enderror" name="project_name" value="{{ old('project_name') }}" required autocomplete="project_name" autofocus>
                                    @error('project_name')
                                        <span class="invalid-feedback" role="alert">
                                            <strong>{{ $message }}</strong>
                                        </span>
                                    @enderror
                                </div>
                            </div>
     
                            <div class="form-group d-flex mt-3 mb-0">
                                <div class="col-md-10 col-12 d-flex justify-content-end">
                                    <a href="{{ route('projects.index') }}" class="mr-3 btn btn-secondary">戻る</a>
                                    <button type="submit" class="btn btn-primary">作成</button>
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection

プロジェクト作成時に必要な情報は作成するプロジェクト名だけなので、必要なinput要素は1つだけです。
また、formのaction属性route('projects.store')を指定しているので、フォームが送信されるとプロジェクト作成処理に処理を渡すことができます。

また、後ほどバリデーションなどを実装するので、バリデーションメッセージが出力できるように記述しています。

プロジェクト一覧画面のリンクを変更

プロジェクト一覧画面の追加ボタンからプロジェクト作成画面に遷移できるように、リンクを変更しておきましょう。

task-app/resources/views/projects/index.blade.phpを下記の通り編集してください。

resources/views/projects/index.blade.php
@extends('layouts.layout')

@section('title')
    プロジェクト一覧
@endsection

@section('content')
    <div class="container mt-4">
        <div class="row">
            <div class="col col-md-6 offset-md-3">
                <div class="card">
                    <div class="card-header bg-dark text-light d-flex justify-content-between align-items-center">
                        <p class="mb-0 h5">プロジェクト</p>
                        <a href="{{ route('projects.create') }}" class="btn btn-primary">追加</a>
                    </div>
                    <table class="table table-hover mb-0">
                        <tbody class="text-center">
                            @foreach ($projects as $project)
                                <tr>
                                    <td><a href="{{ route('tasks.index', $project->id) }}">{{ $project->project_name }}</a></td>
                                </tr>
                            @endforeach
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
@endsection

変更した点は追加ボタンhref属性です。
href属性に{{ route('projects.create') }}と指定することで、プロジェクト作成画面に遷移することができるようになりました。

プロジェクト作成処理

プロジェクト作成画面を表示することができるようになったので、次はプロジェクト作成処理を記述していきましょう。

コントローラー編集

task-app/app/Http/Controllers/ProjectController.phpを下記の通り編集してください。

ProjectController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\Project; // ここを追加

class ProjectController extends Controller
{
    /**
     * プロジェクト一覧画面
     */
    public function index()
    {
        // ログインユーザーが作成した全てのプロジェクトを取得
        $projects = Auth::user()->projects->all();

        return view('projects.index', compact('projects'));
    }

    /**
     * プロジェクト作成画面
     */
    public function create()
    {
        return view('projects.create');
    }

    /**
     * プロジェクト作成処理
     */
    public function store(Request $request)
    {
        // プロジェクト作成処理
        $project = Project::create([
            'project_name' => $request->project_name,
            'user_id' => Auth::id(),
        ]);

        return redirect()->route('projects.index');
    }
}

フォームで入力された値は$requestという引数で受け取っています。
また、データを作成する時のメソッドはcreateメソッドを使用しています。

project_nameにはフォームで入力された値を入れています。
一方user_idには現在ログインしているユーザーのIDを入れています。
Auth::id()と記述することでユーザーのIDを取得することができるので覚えておきましょう。

処理が完了したら、プロジェクト一覧画面へリダイレクトしています。

これでプロジェクト作成ができるようになったので、各自動作確認をしておきましょう!

バリデーション

次に、プロジェクト作成時のバリデーションを実装していきます。
ターミナルで下記コマンドをtask-appディレクトリ上で実行してください。

コマンド
$ ./vendor/bin/sail php artisan make:request StoreProjectRequest

作成したtask-app/app/Http/Requests/StoreProjectRequest.phpを下記の通り編集してください。

StoreProjectRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

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

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, mixed>
     */
    public function rules()
    {
        return [
            'project_name' => 'required|max:30|string',
        ];
    }

    public function attributes()
    {
        return [
            'project_name' => 'プロジェクト名',
        ];
    }
}

project_nameは必須であり、最大文字数を30文字で文字列が保存されるようにバリデーションされています。

後は作成したStoreProjectRequestクラスProjectコントローラーで読み込むように処理を追加しましょう。

task-app/app/Http/Controllers/ProjectController.phpを下記の通り編集してください。

ProjectController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\Project;
use App\Http\Requests\StoreProjectRequest; // ここを追加

class ProjectController extends Controller
{
    /**
     * プロジェクト一覧画面
     */
    public function index()
    {
        // ログインユーザーが作成した全てのプロジェクトを取得
        $projects = Auth::user()->projects->all();

        return view('projects.index', compact('projects'));
    }

    /**
     * プロジェクト作成画面
     */
    public function create()
    {
        return view('projects.create');
    }

    /**
     * プロジェクト作成処理
     */
    public function store(StoreProjectRequest $request)
    {
        // プロジェクト作成処理
        $project = Project::create([
            'project_name' => $request->project_name,
            'user_id' => Auth::id(),
        ]);

        return redirect()->route('projects.index');
    }
}

作成したフォームリクエストをProjectコントローラーで使用できるようにuse文を使用しています。
また、storeメソッドの引数をRequest $requestからStoreProjectRequest $requestに変更しています。

作成したフォームリクエストを適用させるのはこれだけの変更でOKです。

さっそくhttp://localhost/project/createにアクセスして、31文字以上のテキストを入力して作成ボタンをクリックしましょう。

下記画像のようにバリデーションメッセージが表示されればOKです。
スクリーンショット 2022-07-02 13.21.15.png

エラー処理

データベースの操作をしているのでエラー処理をしておきましょう。

実装する内容は下記の通りです。

  1. try-catch文
  2. トランザクション
  3. ログ出力
  4. エラー画面への遷移

task-app/app/Http/Controllers/ProjectController.phpを下記の通り編集してください。

ProjectController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\Project;
use App\Http\Requests\StoreProjectRequest;
use Illuminate\Support\Facades\DB; // ここを追加
use Illuminate\Support\Facades\Log; // ここを追加

class ProjectController extends Controller
{
    /**
     * プロジェクト一覧画面
     */
    public function index()
    {
        // ログインユーザーが作成した全てのプロジェクトを取得
        $projects = Auth::user()->projects->all();

        return view('projects.index', compact('projects'));
    }

    /**
     * プロジェクト作成画面
     */
    public function create()
    {
        return view('projects.create');
    }

    /**
     * プロジェクト作成処理
     */
    public function store(StoreProjectRequest $request)
    {
        // トランザクション開始
        DB::beginTransaction();

        try {
            // プロジェクト作成処理
            $project = Project::create([
                'project_name' => $request->project_name,
                'user_id' => Auth::id(),
            ]);

            // トランザクションコミット
            DB::commit();
        } catch(\Exception $e) {
            // トランザクションロールバック
            DB::rollBack();

            // ログ出力
            Log::debug($e);

            // エラー画面遷移
            abort(500);
        }

        return redirect()->route('projects.index');
    }
}

Laravel教材と実装している内容は全く同じです。
これでエラー処理も実装できたので、プロジェクト作成の実装は完了です。

タスク作成

次は、タスク一覧画面にあった、追加ボタンからタスクを追加できるようにしていきましょう。

ルーティング

まずはルーティングから行っていきます。
task-app/routes/web.phpを下記の通り編集してください。

web.php
<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ProjectController;
use App\Http\Controllers\TaskController;

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

Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(['auth'])->name('dashboard');

// ログイン必須ルート
Route::middleware('auth')->group(function () {
    // プロジェクト一覧画面
    Route::get('projects', [ProjectController::class, 'index'])->name('projects.index');

    // プロジェクト作成画面
    Route::get('projects/create', [ProjectController::class, 'create'])->name('projects.create');

    // プロジェクト作成処理
    Route::post('projects/store', [ProjectController::class, 'store'])->name('projects.store');

    // タスク一覧画面
    Route::get('projects/{id}/tasks', [TaskController::class, 'index'])->name('tasks.index');

    // タスク作成画面
    Route::get('projects/{id}/tasks/create', [TaskController::class, 'create'])->name('tasks.create'); // ここを追加

    // タスク作成処理
    Route::post('projects/{id}/tasks/store', [TaskController::class, 'store'])->name('tasks.store'); // ここを追加
});

require __DIR__.'/auth.php';

2つのルートを追加しています。
1つ目がタスク作成画面を表示させるためのcreateメソッドに処理を渡すルートで、2つ目はタスク作成処理をさせるstoreメソッドに処理を渡すルートです。

タスク作成画面表示

それではタスク作成画面を表示させる処理やビューを作成していきましょう。

コントローラー編集

まずはルートで設定したcreateメソッドを作成していきましょう。
task-app/app/Http/Controllers/TaskController.phpを下記の通り編集してください。

TaskController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Project;

class TaskController extends Controller
{
    /**
     * プロジェクトに紐づくタスク一覧
     */
    public function index($id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        // プロジェクト取得
        $project = Project::find($currentProjectId);

        // 取得したプロジェクトに紐づくタスクを取得
        $tasks = $project->tasks->all();

        return view('tasks.index', compact(
            'currentProjectId',
            'tasks',
        ));
    }

    /**
     * タスク作成画面
     */
    public function create($id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        return view('tasks.create', compact(
            'currentProjectId',
        ));
    }
}

createメソッドが実行されるとprojects/create.blade.phpが表示されるように処理を記述しました。

ビュー作成&編集

http://localhost/projects/1/tasks/createにアクセスがあった場合、Taskコントローラーtasks/create.blade.phpを表示させるように処理を記述したので、create.blade.phpを作成していきましょう。
task-app/resources/views/tasksディレクトリ配下にcreate.blade.phpを作成してください。
コマンドで作成する場合は、ターミナルで下記コマンドをtask-appディレクトリ上で実行してください。

コマンド
$ touch resources/views/tasks/create.blade.php

作成したtask-app/resources/views/tasks/create.blade.phpを下記の通り編集してください。

resources/views/tasks/create.blade.php
@extends('layouts.layout')

@section('title')
    タスク作成
@endsection

@section('content')
    <div class="container mt-4">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header text-center">タスク作成</div>
     
                    <div class="card-body">
                        <form method="POST" action="{{ route('tasks.store', $currentProjectId) }}">
                            @csrf

                            <div class="form-group d-flex flex-column flex-md-row">
                                <label for="task_name" class="col-md-4 col-form-label text-md-right">タスク名:</label>
                                <div class="col-md-6">
                                    <input id="task_name" type="type" class="form-control @error('task_name') is-invalid @enderror" name="task_name" value="{{ old('task_name') }}" required autocomplete="task_name" autofocus>
                                    @error('task_name')
                                        <span class="invalid-feedback" role="alert">
                                            <strong>{{ $message }}</strong>
                                        </span>
                                    @enderror
                                </div>
                            </div>

                            <div class="form-group d-flex flex-column flex-md-row mt-3">
                                <label for="due_date" class="col-md-4 col-form-label text-md-right">期限:</label>
                                <div class="col-md-6">
                                    <input id="due_date" type="date" class="form-control @error('due_date') is-invalid @enderror" name="due_date" value="{{ old('due_date') }}" required autocomplete="due_date" autofocus>
                                    @error('due_date')
                                        <span class="invalid-feedback" role="alert">
                                            <strong>{{ $message }}</strong>
                                        </span>
                                    @enderror
                                </div>
                            </div>

                            <div class="form-group d-flex mt-3 mb-0">
                                <div class="col-md-10 col-12 d-flex justify-content-end">
                                    <button type="submit" class="btn btn-primary">作成</button>
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection

タスク作成時に必要な情報はタスク名、期限の2つなので、必要なinput要素は2つです。
タスクを作成する際にプロジェクトIDが必要になりますが、プロジェクトIDはルートパラメーターとして渡しています。

また、タスク作成時には進捗が必要になりますが、tasksテーブルの設定(マイグレーション)でtask_statusをデフォルトで0(未対応)に設定しているので、特にformで設定する必要はありません。

タスク一覧画面のリンクを変更

タスク一覧画面の追加ボタンからタスク作成画面に遷移できるように、リンクを変更しておきましょう。

task-app/resources/views/tasks/index.blade.phpを下記の通り編集してください。

resources/views/tasks/index.blade.php
@extends('layouts.layout')

@section('title')
    タスク一覧
@endsection

@section('content')
    <div class="container mt-4">
        <div class="row">
            <div class="column col-md-8 offset-md-2 mt-md-0 mt-3">
                <div class="card">
                    <div class="card-header bg-dark text-light d-flex justify-content-between align-items-center">
                        <p class="mb-0 h5">タスク</p>
                        <a href="{{ route('tasks.create', $currentProjectId) }}" class="btn btn-primary">追加</a>
                    </div>
                    <table class="table table-hover mb-0">
                        <thead class="text-light" style="background-color: rgb(106, 106, 106)">
                            <tr class="text-center">
                                <th scope="col"style="width: 65%">タスク名</th>
                                <th scope="col" style="width: 15%">進捗</th>
                                <th scope="col" style="width: 20%">期限</th>
                            </tr>
                        </thead>
                        <tbody class="text-center">
                            @foreach ($tasks as $task)
                                <tr>
                                    <td><a href="#">{{ $task->task_name }}</a></td>
                                    <td><span class="d-inline badge {{ $task->task_status_class }}">{{ $task->task_status_string }}</span></td>
                                    <td>{{ $task->due_date }}</td>
                                </tr>
                            @endforeach
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
@endsection

変更した点は追加ボタンhref属性です。
href属性に{{ route('tasks.create', $currentProjectId) }}と指定することで、タスク作成画面に遷移することができるようになりました。

タスク作成処理

タスク作成画面を表示することができるようになったので、次はタスク作成処理を記述していきましょう。

コントローラー編集

task-app/app/Http/Controllers/TaskController.phpを下記の通り編集してください。

TaskController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Project;
use App\Models\Task; // ここを追加

class TaskController extends Controller
{
    /**
     * プロジェクトに紐づくタスク一覧
     */
    public function index($id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        // プロジェクト取得
        $project = Project::find($currentProjectId);

        // 取得したプロジェクトに紐づくタスクを取得
        $tasks = $project->tasks->all();

        return view('tasks.index', compact(
            'currentProjectId',
            'tasks',
        ));
    }

    /**
     * タスク作成画面
     */
    public function create($id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        return view('tasks.create', compact(
            'currentProjectId',
        ));
    }

    /**
     * タスク作成処理
     */
    public function store(Request $request, $id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        // タスク作成処理
        $task = Task::create([
            'project_id' => $currentProjectId,
            'task_name' => $request->task_name,
            'due_date' => $request->due_date,
        ]);

        return redirect()->route('tasks.index', [
            'id' => $currentProjectId,
        ]);
    }
}

フォームで入力された値は$requestという引数で受け取っています。
また、データを作成する時のメソッドはcreateメソッドを使用しています。

task_namedue_dateにはそれぞれのフォームで入力された値を入れています。
一方project_idにはルートパラメーターで渡されてきた数値を入れています。

処理が完了したら、タスク一覧画面へリダイレクトしています。

これでタスク作成ができるようになったので、各自動作確認をしておきましょう!

バリデーション

次に、タスク作成時のバリデーションを実装していきます。
ターミナルで下記コマンドをtask-appディレクトリ上で実行してください。

コマンド
$ ./vendor/bin/sail php artisan make:request StoreTaskRequest

作成したtask-app/app/Http/Requests/StoreTaskRequest.phpを下記の通り編集してください。

StoreTaskRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

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

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, mixed>
     */
    public function rules()
    {
        return [
            'task_name' => 'required|max:100|string',
            'due_date' => 'required|date|after_or_equal:today',
        ];
    }

    public function attributes()
    {
        return [
            'task_name' => 'タスク名',
            'due_date' => '期限',
        ];
    }

    public function messages()
    {
        return [
            'due_date.after_or_equal' => ':attributeには今日以降の日付を指定してください。',
        ];
    }
}

task_nameのバリデーションは最大文字数が違うだけで、プロジェクト作成時のproject_nameのバリデーションとほぼ同様です。

due_dateのバリデーションにはdate(日付を表す値であること)after_or_equal(特定の日付と同じまたはそれ以降の日付であること)を使用しています。
というのも、タスクの期限日が過去の日付だとおかしいので、after_or_equalの引数としてtodayを指定することで、今日を含んだ未来の日だけを許容することができます。

また、messagesメソッドというものも実装しています。
このメソッドはFormRequestクラス単位でエラーメッセージを定義することができるメソッドです。
'due_date.after_or_equal'とすることで、due_dateafter_or_equalのバリデーションに引っかかった時のみ:attributeには今日以降の日付を指定してください。というバリデーションメッセージを出力するようになります。

:attributeと記述すると、attributesメソッドで記述した期限が:attributeのところに代入され、最終的なバリデーションメッセージは期限には今日以降の日付を指定してくださいとなります。

後は作成したStoreTaskRequestクラスTaskコントローラーで読み込むように処理を追加しましょう。
task-app/app/Http/Controllers/TaskController.phpを下記の通り編集してください。

TaskController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Project;
use App\Models\Task;
use App\Http\Requests\StoreTaskRequest; // ここを追加

class TaskController extends Controller
{
    /**
     * プロジェクトに紐づくタスク一覧
     */
    public function index($id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        // プロジェクト取得
        $project = Project::find($currentProjectId);

        // 取得したプロジェクトに紐づくタスクを取得
        $tasks = $project->tasks->all();

        return view('tasks.index', compact(
            'currentProjectId',
            'tasks',
        ));
    }

    /**
     * タスク作成画面
     */
    public function create($id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        return view('tasks.create', compact(
            'currentProjectId',
        ));
    }

    /**
     * タスク作成処理
     */
    public function store(StoreTaskRequest $request, $id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        // タスク作成処理
        $task = Task::create([
            'project_id' => $currentProjectId,
            'task_name' => $request->task_name,
            'due_date' => $request->due_date,
        ]);

        return redirect()->route('tasks.index', [
            'id' => $currentProjectId,
        ]);
    }
}

作成したフォームリクエストをTaskコントローラーで使用できるようにuse文を使用しています。
また、storeメソッドの引数をRequest $requestからStoreTaskRequest $requestに変更しています。

さっそくhttp://localhost/projects/1/tasks/createにアクセスして、101文字以上のテキストをタスク名に入力し、期限には今日以前の日付を入力して作成ボタンをクリックしましょう。
下記画像のようにバリデーションメッセージが表示されればOKです。
スクリーンショット 2022-07-05 22.32.41.png

エラー処理

最後にエラー処理だけしておきましょう。
task-app/app/Http/Controllers/TaskController.phpを下記の通り編集してください。

TaskController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Project;
use App\Models\Task;
use App\Http\Requests\StoreTaskRequest;
use Illuminate\Support\Facades\DB; // ここを追加
use Illuminate\Support\Facades\Log; // ここを追加

class TaskController extends Controller
{
    /**
     * プロジェクトに紐づくタスク一覧
     */
    public function index($id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        // プロジェクト取得
        $project = Project::find($currentProjectId);

        // 取得したプロジェクトに紐づくタスクを取得
        $tasks = $project->tasks->all();

        return view('tasks.index', compact(
            'currentProjectId',
            'tasks',
        ));
    }

    /**
     * タスク作成画面
     */
    public function create($id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        return view('tasks.create', compact(
            'currentProjectId',
        ));
    }

    /**
     * タスク作成処理
     */
    public function store(StoreTaskRequest $request, $id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        // トランザクション開始
        DB::beginTransaction();

        try {
            // タスク作成処理
            $task = Task::create([
                'project_id' => $currentProjectId,
                'task_name' => $request->task_name,
                'due_date' => $request->due_date,
            ]);

            // トランザクションコミット
            DB::commit();
        } catch(\Exception $e) {
            // トランザクションロールバック
            DB::rollBack();

            // ログ出力
            Log::debug($e);

            // エラー画面遷移
            abort(500);
        } 

        return redirect()->route('tasks.index', [
            'id' => $currentProjectId,
        ]);
    }
}

これまでのエラー処理で実装している内容と全く同じです。
これでタスク作成の実装は完了です。

タスク編集

次は、タスク一覧画面で各タスク名をクリックされた時に、タスクを編集できるようにしていきましょう。

ルーティング

まずはルーティングから行っていきます。
task-app/routes/web.phpを下記の通り編集してください。

web.php
<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ProjectController;
use App\Http\Controllers\TaskController;

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

Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(['auth'])->name('dashboard');

// ログイン必須ルート
Route::middleware('auth')->group(function () {
    // プロジェクト一覧画面
    Route::get('projects', [ProjectController::class, 'index'])->name('projects.index');

    // プロジェクト作成画面
    Route::get('projects/create', [ProjectController::class, 'create'])->name('projects.create');

    // プロジェクト作成処理
    Route::post('projects/store', [ProjectController::class, 'store'])->name('projects.store');

    // タスク一覧画面
    Route::get('projects/{id}/tasks', [TaskController::class, 'index'])->name('tasks.index');

    // タスク作成画面
    Route::get('projects/{id}/tasks/create', [TaskController::class, 'create'])->name('tasks.create');

    // タスク作成処理
    Route::post('projects/{id}/tasks/store', [TaskController::class, 'store'])->name('tasks.store');

    // タスク編集画面
    Route::get('projects/{id}/tasks/edit/{taskId}', [TaskController::class, 'edit'])->name('tasks.edit'); // ここを追加

    // タスク編集処理
    Route::post('projects/{id}/tasks/update/{taskId}', [TaskController::class, 'update'])->name('tasks.update'); // ここを追加
});

require __DIR__.'/auth.php';

2つのルートを追加しています。
1つ目がタスク編集画面を表示させるためのeditメソッドに処理を渡すルートで、2つ目はタスク編集処理をさせるupdateメソッドに処理を渡すルートです。

タスク編集画面表示

それではタスク編集画面を表示させる処理やビューを作成していきましょう。

コントローラー編集

まずはルートで設定したeditメソッドを作成していきましょう。
task-app/app/Http/Controllers/TaskController.phpを下記の通り編集してください。

TaskControler.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Project;
use App\Models\Task;
use App\Http\Requests\StoreTaskRequest;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class TaskController extends Controller
{
    /**
     * プロジェクトに紐づくタスク一覧
     */
    public function index($id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        // プロジェクト取得
        $project = Project::find($currentProjectId);

        // 取得したプロジェクトに紐づくタスクを取得
        $tasks = $project->tasks->all();

        return view('tasks.index', compact(
            'currentProjectId',
            'tasks',
        ));
    }

    /**
     * タスク作成画面
     */
    public function create($id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        return view('tasks.create', compact(
            'currentProjectId',
        ));
    }

    /**
     * タスク作成処理
     */
    public function store(StoreTaskRequest $request, $id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        // トランザクション開始
        DB::beginTransaction();

        try {
            // タスク作成処理
            $task = Task::create([
                'project_id' => $currentProjectId,
                'task_name' => $request->task_name,
                'due_date' => $request->due_date,
            ]);

            // トランザクションコミット
            DB::commit();
        } catch(\Exception $e) {
            // トランザクションロールバック
            DB::rollBack();

            // ログ出力
            Log::debug($e);

            // エラー画面遷移
            abort(500);
        } 

        return redirect()->route('tasks.index', [
            'id' => $currentProjectId,
        ]);
    }

    /**
     * タスク編集画面
     */
    public function edit($id, $taskId)
    {
        // タスクを取得
        $task = Task::find($taskId);

        // 進捗のテキスト(Taskモデルの定数取得)
        $taskStatusStrings = Task::TASK_STATUS_STRING;

        // 進捗のクラス(Taskモデルの定数取得)
        $taskStatusClasses = Task::TASK_STATUS_CLASS;

        return view('tasks.edit', compact(
            'task',
            'taskStatusStrings',
            'taskStatusClasses',
        ));
    }
}

今回はルートパラメーターが2つ存在しています。
1つがプロジェクトIDでもう1つがタスクIDです。
それぞれ$id$taskIdという引数で受け取っています。

まずはfindメソッドを使用して編集するタスクを取得しましょう。
次に、進捗がデータベース上で数値として保存されているので、数値に結びつくテキストをTaskモデルから取得します。

Taskモデルから定数であるTASK_STATUS_STRINGを取得するためにはTask::TASK_STATUS_STRINGと記述します。

また、Bootstrapで使用するクラス名も定数化していたので、そちらもTask::TASK_STATUS_CLASSとすることで取得することができます。

それぞれを$taskStatusStrings$taskStatusClassesという変数に格納しているので、これらの変数の中身を確認したい場合は、$taskStatusClasses = Task::TASK_STATUS_CLASS;の後にdd($taskStatusStrings, $taskStatusClasses)と記述しましょう。
下記画像の値が入っていればOKです!
スクリーンショット 2022-07-06 18.31.26.png
これら取得した値をtasks/edit.blade.phpに渡しましょう。

ビュー作成&編集

http://localhost/projects/1/tasks/edit/1にアクセスがあった場合、Taskコントローラーtasks/edit.blade.phpを表示させるように処理を記述したので、edit.blade.phpを作成していきましょう。
task-app/resources/views/tasksディレクトリ配下にedit.blade.phpを作成してください。
コマンドで作成する場合は、ターミナルで下記コマンドをtask-appディレクトリ上で実行してください。

ターミナル
$ touch resources/views/tasks/edit.blade.php

作成したtask-app/resources/views/tasks/edit.blade.phpを下記の通り編集してください。

resources/views/tasks/edit.blade.php
@extends('layouts.layout')

@section('title')
    タスク編集
@endsection

@section('content')
    <div class="container mt-4">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header text-center">タスク編集</div>

                    <div class="card-body">
                        <form method="POST" action="{{ route('tasks.update', [$task->project_id, $task->id]) }}">
                            @csrf

                            <div class="form-group d-flex flex-column flex-md-row">
                                <label for="task_name" class="col-md-4 col-form-label text-md-right">タスク名:</label>
                                <div class="col-md-6">
                                    <input id="task_name" type="type" class="form-control @error('task_name') is-invalid @enderror" name="task_name" value="{{ old('task_name', $task->task_name) }}" required autocomplete="task_name" autofocus>
                                    @error('task_name')
                                        <span class="invalid-feedback" role="alert">
                                            <strong>{{ $message }}</strong>
                                        </span>
                                    @enderror
                                </div>
                            </div>

                            <div class="form-group d-flex flex-column flex-md-row mt-3">
                                <label for="task_status" class="col-md-4 col-form-label text-md-right">進捗:</label>
                                <div class="col-md-6">
                                    <select name="task_status" id="task_status" class="form-select @error('task_status') is-invalid @enderror">
                                        @foreach ($taskStatusStrings as $key => $taskStatusString)
                                            <option @if ($key == old('task_status', $task->task_status)) selected @endif value="{{ $key }}">{{ $taskStatusString }}</option>
                                        @endforeach
                                    </select>
                                    @error('task_status')
                                        <span class="invalid-feedback" role="alert">
                                            <strong>{{ $message }}</strong>
                                        </span>
                                    @enderror
                                </div>
                            </div>

                            <div class="form-group d-flex flex-column flex-md-row mt-3">
                                <label for="due_date" class="col-md-4 col-form-label text-md-right">期限:</label>
                                <div class="col-md-6">
                                    <input id="due_date" type="date" class="form-control @error('due_date') is-invalid @enderror" name="due_date" value="{{ old('due_date', $task->due_date) }}" required autocomplete="due_date" autofocus>
                                    @error('due_date')
                                        <span class="invalid-feedback" role="alert">
                                            <strong>{{ $message }}</strong>
                                        </span>
                                    @enderror
                                </div>
                            </div>

                            <div class="form-group d-flex mt-3 mb-0">
                                <div class="col-md-10 col-12 d-flex justify-content-end">
                                    <button type="submit" class="btn btn-primary">編集</button>
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection

今回は編集画面ということでoldメソッドの第二引数にデフォルト値を指定しておきます。
例えばタスク名のinput要素oldメソッドの第二引数にはtask->task_nameが指定されています。
この場合、画面が表示された直後はTaskコントローラーで取得したタスク情報が表示されます。

進捗の場合はセレクトボックスになっているので、option要素に工夫が必要になります。
@if ($key == old('task_status', $task->task_status)) selected @endifと記述していますが、これはforeach$keyを使用して、完了処理済み処理中未対応のどれが選択されているのかを表現することができます。

というのも、変数$taskStatusStringsには4つの要素があり、$keyには0から3の数値が入っています。
またtask_statusにも0から3の数値が保存されています。

この数値が$keyold('task_status', $task->task_status)が等しい時はselected属性が付与されます。
例えば、タスクの進捗が1だった場合は$key1と等しくなるので、処理中が選択されます。

これで編集画面ができました。

タスク一覧画面のリンクを変更

タスク一覧画面から各タスク名をクリックした時に、タスク編集画面に遷移できるようリンクを変更しておきましょう。

task-app/resources/views/tasks/index.blade.phpを下記の通り編集してください。

resources/views/tasks/index.blade.php
@extends('layouts.layout')

@section('title')
    タスク一覧
@endsection

@section('content')
    <div class="container mt-4">
        <div class="row">
            <div class="column col-md-8 offset-md-2 mt-md-0 mt-3">
                <div class="card">
                    <div class="card-header bg-dark text-light d-flex justify-content-between align-items-center">
                        <p class="mb-0 h5">タスク</p>
                        <a href="{{ route('tasks.create', $currentProjectId) }}" class="btn btn-primary">追加</a>
                    </div>
                    <table class="table table-hover mb-0">
                        <thead class="text-light" style="background-color: rgb(106, 106, 106)">
                            <tr class="text-center">
                                <th scope="col"style="width: 65%">タスク名</th>
                                <th scope="col" style="width: 15%">進捗</th>
                                <th scope="col" style="width: 20%">期限</th>
                            </tr>
                        </thead>
                        <tbody class="text-center">
                            @foreach ($tasks as $task)
                                <tr>
                                    <td><a href="{{ route('tasks.edit', [$currentProjectId, $task->id]) }}">{{ $task->task_name }}</a></td>
                                    <td><span class="d-inline badge {{ $task->task_status_class }}">{{ $task->task_status_string }}</span></td>
                                    <td>{{ $task->due_date }}</td>
                                </tr>
                            @endforeach
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
@endsection

変更した点は各タスク名のhref属性です。
href属性に{{ route('tasks.edit', [$currentProjectId, $task->id]) }}と指定することで、タスク編集画面に遷移することができるようになりました。

また、routeメソッドの第二引数には配列でプロジェクトIDとタスクIDを指定しています。
複数のパラメーターをメソッドに渡したい場合は配列を使いましょう。

これで各タスク名をクリックすると、タスク編集画面に遷移できるようになりました。

タスク編集処理

タスク編集画面を表示することができるようになったので、次はタスク編集処理を記述していきましょう。

コントローラー編集

task-app/app/Http/Controllers/TaskController.phpを下記の通り編集してください。

TaskControler.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Project;
use App\Models\Task;
use App\Http\Requests\StoreTaskRequest;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class TaskController extends Controller
{
    /**
     * プロジェクトに紐づくタスク一覧
     */
    public function index($id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        // プロジェクト取得
        $project = Project::find($currentProjectId);

        // 取得したプロジェクトに紐づくタスクを取得
        $tasks = $project->tasks->all();

        return view('tasks.index', compact(
            'currentProjectId',
            'tasks',
        ));
    }

    /**
     * タスク作成画面
     */
    public function create($id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        return view('tasks.create', compact(
            'currentProjectId',
        ));
    }

    /**
     * タスク作成処理
     */
    public function store(StoreTaskRequest $request, $id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        // トランザクション開始
        DB::beginTransaction();

        try {
            // タスク作成処理
            $task = Task::create([
                'project_id' => $currentProjectId,
                'task_name' => $request->task_name,
                'due_date' => $request->due_date,
            ]);

            // トランザクションコミット
            DB::commit();
        } catch(\Exception $e) {
            // トランザクションロールバック
            DB::rollBack();

            // ログ出力
            Log::debug($e);

            // エラー画面遷移
            abort(500);
        } 

        return redirect()->route('tasks.index', [
            'id' => $currentProjectId,
        ]);
    }

    /**
     * タスク編集画面
     */
    public function edit($id, $taskId)
    {
        // タスクを取得
        $task = Task::find($taskId);

        // 進捗のテキスト(Taskモデルの定数取得)
        $taskStatusStrings = Task::TASK_STATUS_STRING;

        // 進捗のクラス(Taskモデルの定数取得)
        $taskStatusClasses = Task::TASK_STATUS_CLASS;

        return view('tasks.edit', compact(
            'task',
            'taskStatusStrings',
            'taskStatusClasses',
        ));
    }

    /**
     * タスク編集処理
     */
    public function update(Request $request, $id, $taskId)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        // タスクを取得
        $task = Task::find($taskId);

        // タスク編集処理(fill)
        $task->fill([
            'task_name' => $request->task_name,
            'task_status' => $request->task_status,
            'due_date' => $request->due_date,
        ]);

        // タスク編集処理(save)
        $task->save();

        return redirect()->route('tasks.index', [
            'id' => $currentProjectId,
        ]);
    }
}

フォームで入力された値は$requestという引数で受け取っています。
また、データを更新する時のメソッドはfillメソッド + saveメソッドを使用しています。

task_nametask_statusdue_dateにはそれぞれのフォームで入力された値を入れています。

更新処理が完了したら、タスク一覧画面へリダイレクトしています。
これでタスク編集ができるようになったので、各自動作確認をしておきましょう!

バリデーション

次に、タスク編集時のバリデーションを実装していきます。
ターミナルで下記コマンドをtask-appディレクトリ上で実行してください。

コマンド
$ ./vendor/bin/sail php artisan make:request UpdateTaskRequest
UpdateTaskRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule; // ここを追加
use App\Models\Task; // ここを追加

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

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, mixed>
     */
    public function rules()
    {
        $myTaskStatusRule = Rule::in(array_keys(Task::TASK_STATUS_STRING));

        return [
            'task_name' => 'required|max:100|string',
            'task_status' => ['required', $myTaskStatusRule],
            'due_date' => 'required|date',
        ];
    }

    public function attributes()
    {
        return [
            'task_name' => 'タスク名',
            'task_status' => '進捗',
            'due_date' => '期限',
        ];
    }

    public function messages()
    {
        $statuses = implode('、', array_values(Task::TASK_STATUS_STRING));

        return [
            'task_status.in' => ':attributeには' . $statuses .'のいずれかを選択してください。',
        ];
    }
}

進捗(task_status)には、入力値が0~3(完了、処理済み、処理中、未対応)に含まれているか検証する inを使用します。

array_keys(Task::TASK_STATUS_STRING)で配列として0~3を取得できるので、inメソッドを使ってルールの文字列を作成しています。

つまり、Rule::in(array_keys(Task::TASK_STATUS_STRING));と記述することでin(0, 1, 2, 3)となります。
それが変数$myTaskStatusRuleに代入されています。

結果として出力されるルールは以下のようになります。
'task_status' => 'required|in(0, 1, 2, 3)'

後は作成したUpdateTaskRequestクラスTaskコントローラーで読み込むように処理を追加しましょう。
task-app/app/Http/Controllers/TaskController.phpを下記の通り編集してください。

TaskController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Project;
use App\Models\Task;
use App\Http\Requests\StoreTaskRequest;
use App\Http\Requests\UpdateTaskRequest; // ここを追加
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class TaskController extends Controller
{
    /**
     * プロジェクトに紐づくタスク一覧
     */
    public function index($id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        // プロジェクト取得
        $project = Project::find($currentProjectId);

        // 取得したプロジェクトに紐づくタスクを取得
        $tasks = $project->tasks->all();

        return view('tasks.index', compact(
            'currentProjectId',
            'tasks',
        ));
    }

    /**
     * タスク作成画面
     */
    public function create($id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        return view('tasks.create', compact(
            'currentProjectId',
        ));
    }

    /**
     * タスク作成処理
     */
    public function store(StoreTaskRequest $request, $id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        // トランザクション開始
        DB::beginTransaction();

        try {
            // タスク作成処理
            $task = Task::create([
                'project_id' => $currentProjectId,
                'task_name' => $request->task_name,
                'due_date' => $request->due_date,
            ]);

            // トランザクションコミット
            DB::commit();
        } catch(\Exception $e) {
            // トランザクションロールバック
            DB::rollBack();

            // ログ出力
            Log::debug($e);

            // エラー画面遷移
            abort(500);
        } 

        return redirect()->route('tasks.index', [
            'id' => $currentProjectId,
        ]);
    }

    /**
     * タスク編集画面
     */
    public function edit($id, $taskId)
    {
        // タスクを取得
        $task = Task::find($taskId);

        // 進捗のテキスト(Taskモデルの定数取得)
        $taskStatusStrings = Task::TASK_STATUS_STRING;

        // 進捗のクラス(Taskモデルの定数取得)
        $taskStatusClasses = Task::TASK_STATUS_CLASS;

        return view('tasks.edit', compact(
            'task',
            'taskStatusStrings',
            'taskStatusClasses',
        ));
    }

    /**
     * タスク編集処理
     */
    public function update(UpdateTaskRequest $request, $id, $taskId)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        // タスクを取得
        $task = Task::find($taskId);

        // タスク編集処理(fill)
        $task->fill([
            'task_name' => $request->task_name,
            'task_status' => $request->task_status,
            'due_date' => $request->due_date,
        ]);

        // タスク編集処理(save)
        $task->save();

        return redirect()->route('tasks.index', [
            'id' => $currentProjectId,
        ]);
    }
}

これで、もしtask_status0~3以外の数字入力されていた場合は、messagesメソッドで定義している:attributeには$statusesのいずれかを選択してください。というバリデーションメッセージが出力されます。

ちなみに、変数$statusesには完了処理済み処理中未対応という文字列が入っています。
そのため、バリデーションに引っかかった場合は進捗には未対応、処理中、処理済み、完了のいずれかを選択してください。というバリデーションメッセージが出力されるようになります。

エラー処理

最後にエラー処理だけしておきましょう。
task-app/app/Http/Controllers/TaskController.phpを下記の通り編集してください。

TaskController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Project;
use App\Models\Task;
use App\Http\Requests\StoreTaskRequest;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class TaskController extends Controller
{
    /**
     * プロジェクトに紐づくタスク一覧
     */
    public function index($id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        // プロジェクト取得
        $project = Project::find($currentProjectId);

        // 取得したプロジェクトに紐づくタスクを取得
        $tasks = $project->tasks->all();

        return view('tasks.index', compact(
            'currentProjectId',
            'tasks',
        ));
    }

    /**
     * タスク作成画面
     */
    public function create($id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        return view('tasks.create', compact(
            'currentProjectId',
        ));
    }

    /**
     * タスク作成処理
     */
    public function store(StoreTaskRequest $request, $id)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        // トランザクション開始
        DB::beginTransaction();

        try {
            // タスク作成処理
            $task = Task::create([
                'project_id' => $currentProjectId,
                'task_name' => $request->task_name,
                'due_date' => $request->due_date,
            ]);

            // トランザクションコミット
            DB::commit();
        } catch(\Exception $e) {
            // トランザクションロールバック
            DB::rollBack();

            // ログ出力
            Log::debug($e);

            // エラー画面遷移
            abort(500);
        } 

        return redirect()->route('tasks.index', [
            'id' => $currentProjectId,
        ]);
    }

    /**
     * タスク編集画面
     */
    public function edit($id, $taskId)
    {
        // タスクを取得
        $task = Task::find($taskId);

        // 進捗のテキスト(Taskモデルの定数取得)
        $taskStatusStrings = Task::TASK_STATUS_STRING;

        // 進捗のクラス(Taskモデルの定数取得)
        $taskStatusClasses = Task::TASK_STATUS_CLASS;

        return view('tasks.edit', compact(
            'task',
            'taskStatusStrings',
            'taskStatusClasses',
        ));
    }

    /**
     * タスク編集処理
     */
    public function update(UpdateTaskRequest $request, $id, $taskId)
    {
        // URLで送られてきたプロジェクトID
        $currentProjectId = $id;

        // タスクを取得
        $task = Task::find($taskId);

        // トランザクション開始
        DB::beginTransaction();

        try {
            // タスク編集処理(fill)
            $task->fill([
                'task_name' => $request->task_name,
                'task_status' => $request->task_status,
                'due_date' => $request->due_date,
            ]);

            // タスク編集処理(save)
            $task->save();

            // トランザクションコミット
            DB::commit();
        } catch(\Exception $e) {
            // トランザクションロールバック
            DB::rollBack();

            // ログ出力
            Log::debug($e);

            // エラー画面遷移
            abort(500);
        }

        return redirect()->route('tasks.index', [
            'id' => $currentProjectId,
        ]);
    }
}

これまでのエラー処理で実装している内容と全く同じです。
これでタスク編集の実装は完了です。

0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up