Docker×Laravel8でもくもく会アプリを作成する登録処理編です。
まだ前回の記事を読まれていない方は、続きになるので先に読むことをおすすめします。
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
登録処理の流れ
登録処理は、以下のステップで実装します。
①ルーティングを追加する
まずは、登録処理のルーティングを追加していきましょう。
追加する項目
// もくもく会登録処理
Route::post('/event/create', [EventController::class, 'create'])
->name('event.create');
全体
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\EventController;
use App\Http\Controllers\CategoryController;
// もくもく会一覧画面
Route::get('/', [EventController::class, 'index'])
->name('event.index');
// もくもく会登録画面
Route::get('/event/register', [EventController::class, 'register'])
->name('event.register');
// もくもく会登録処理
Route::post('/event/create', [EventController::class, 'create'])
->name('event.create');
// カテゴリー一覧画面
Route::get('/category/index', [CategoryController::class, 'index'])
->name('category.index');
②Eventコントローラーに登録処理メソッドを追加する
続いて、Eventコントローラーに登録処理のメソッドを書きます。※create
追加項目
/**
* もくもく会登録処理
*/
public function create(Request $request)
{
return redirect()->route('event.index');
}
全体像
<?php
namespace App\Http\Controllers;
use App\Models\Event;
use App\Models\category;
use Illuminate\Http\Request;
class EventController extends Controller
{
public function __construct()
{
$this->event = new Event();
$this->category = new Category();
}
/**
* イベント一覧画面
*/
public function index()
{
// Eloquentでeventsテーブルにあるデータを全て取得
$events = $this->event->allEventsData();
return view('event.index', compact('events'));
}
/**
* もくもく会登録画面
*/
public function register()
{
$categories = $this->category->allCategoriesData();
return view('event.register', compact('categories'));
}
/**
* もくもく会登録処理
*/
public function create(Request $request)
{
return redirect()->route('event.index');
}
}
createメソッドでは、登録処理に成功したときにもくもく会一覧画面にリダイレクトするよう記述してます。
redirect()->route(‘遷移したいページ’)でOKです。
③ビューでformアクションやメソッドに追記する
続いて、ビューのformアクションやメソッドに追記します。
<div class="container">
<form action="{{ route('event.create') }}" method="POST">
@csrf
... 登録画面 ...
</form>
</div>
これでもくもく会を開催するボタンを押下したときに、EventコントローラーのcreateメソッドがPOST形式で呼ばれて登録処理が走ります。
あとは、Eventコントローラーに登録処理を書いていき、ビューも少し修正していく形で登録処理は完成です。
動作確認
グリーンの開催ボタンを押下※フォームには何も入力しなくてOK
一覧画面に遷移する
フォームに値を入れてDBにデータが登録できるようにする
簡単に登録処理(値は空の状態)の動作確認ができたところで、次はフォームに値を入れてDBにデータを登録できる状態にします。
実装のステップは以下です。
フォームの値に何が入っているか理解する
登録処理を実装する前に、フォームにどんな値が入るのか確認しましょう。
まずはLaravelのRequestについておさらいです。
Laravelの機能として、Requestがありましたね。
bladeファイルで、<input type=”” name=”aaa”>と、nameに定義し、それをコントローラーで$request->name属性の値つまり、$request->aaaで入力した値が取得できます。
登録処理で、create(Request $request)としてますが、これはLaravel特有の書き方なので、あまり深く考えずに、ビューのname属性の値をコントローラーで$request->name属性とすれば取得できるんだ!程度に理解しましょう。
Laravel8公式 Requestの入力に詳細が載っています。
流れがわかったところでdd関数を使ってデバッグし、実際に$requestにはどうやって値が送られるのかみていきます。
登録画面のタイトルでテストと入力し、
それをコントローラーで受け取ります。
public function create(Request $request)
{
dd($request->title);
フォームに入力したテストを取得できました。
開催日についても同様に、dd関数を使ってデバッグします。まずはフォームに値を選択
public function create(Request $request)
{
dd($request->date);
値を取得できました。
ちなみにこの後、モデルに$requestを渡しますが、$requestに何が入っているか確認しましょう。
登録画面で全てのフォームに値を入力してください。
そして、dd関数で$requestの値を見ます。
public function create(Request $request)
{
dd($request);
request > parametersに値が格納されている。
$requestには、フォームに入力した内容が全て入っており、$request->titleなどでそれぞれの値にアクセスできます。
Eventモデルに登録処理のメソッドを追加する
Eventモデルに登録処理を記述しましょう。
追加する項目
/**
* 登録処理 eventsテーブルにデータをinsert
*
*/
public function insertEventData($request)
{
return $this->create([
'category_id' => $request->category_id,
'title' => $request->title,
'date' => $request->date,
'start_time' => $request->start_time,
'end_time' => $request->end_time,
'content' => $request->content,
'entry_fee' => $request->entry_fee,
]);
}
Eventモデル全体像
<?php
namespace App\Models;
use App\Models\Category;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Event extends Model
{
use HasFactory;
// モデルに関連づけるテーブル
protected $table = 'events';
// テーブルに関連づける主キー
protected $primaryKey = 'event_id';
// 登録・編集ができるカラム
protected $fillable = [
'category_id',
'title',
'date',
'start_time',
'end_time',
'content',
'entry_fee',
];
/**
* カテゴリーリレーション
*/
public function category()
{
return $this->belongsTo(Category::class, 'category_id', 'category_id');
}
/**
* eventsテーブルのレコードを全件取得
*
* @param void
* @return Event eventsテーブル
*/
public function allEventsData()
{
return $this->get();
}
/**
* 登録処理 eventsテーブルにデータをinsert
*
*/
public function insertEventData($request)
{
return $this->create([
'category_id' => $request->category_id,
'title' => $request->title,
'date' => $request->date,
'start_time' => $request->start_time,
'end_time' => $request->end_time,
'content' => $request->content,
'entry_fee' => $request->entry_fee,
]);
}
}
createメソッドを使えば、DBに値をinsertすることができます。
コントローラーに登録処理の関数を呼び出す
Eventモデルに登録処理を定義したので、コントローラーで関数を呼び出します。
/**
* もくもく会登録処理
*/
public function create(Request $request)
{
// リクエストされたデータをもとにeventsテーブルにデータをinsert
$insertEvent = $this->event->insertEventData($request);
return redirect()->route('event.index');
}
③DBにデータがinsertできるか確認
上記までで登録処理ができたので、DBに値が入るか確認しましよう。
登録画面で適当にフォームに値を入力し、phpmyadminを開きます。※全て入力しないとエラーになります。
DBにもデータがinsertできていることがわかりました。
④より安全にデータを扱うため、トランザクションをつける
DBにデータをinsertできましたが、トランザクションをつけて安全にデータを扱いましょう。※よりステップアップしたい方向けなので、飛ばしてもOKです。
実務では何らかのエラーでデータの登録・更新・削除の失敗があった場合、データの整合性が取れないとまずいです。
トランザクションをつけることで、登録処理であれば、登録処理の一連の流れが全て成功した時にDBにデータをinsertします。失敗すれば、DBにデータの処理を実行しません。
<?php
namespace App\Http\Controllers;
use App\Models\Event;
use App\Models\category;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB; // 追加
class EventController extends Controller
{
/**
* もくもく会登録処理
*/
public function create(Request $request)
{
try {
// トランザクション開始
DB::beginTransaction();
// リクエストされたデータをもとにeventsテーブルにデータをinsert
$insertEvent = $this->event->insertEventData($request);
// 処理に成功したらコミット
DB::commit();
} catch (\Throwable $e) {
// 処理に失敗したらロールバック
DB::rollback();
// 例外を投げる
throw $e;
}
return redirect()->route('event.index');
}
コントローラー冒頭に、use Illuminate\Support\Facades\DB;を追加して、DB::〇〇が使えるようにしましょう。
Throwableで全異常を検知できます。
これでひとまずトランザクションを使ってデータの登録処理を安全に扱うことができました。
ただ、このままでは以上が起きた際にユーザー側に、
このようなエラー文を投げるだけなので、親切ではありません。
登録処理に失敗した場合は、一覧画面に遷移させ、フラッシュメッセージで登録処理に失敗したことを伝えましょう。
フラッシュメーセージを表示させる
登録処理に成功したら、一覧画面にリダイレクトした上で「登録処理に成功」のメッセージを表示し、登録処理に失敗したら、一覧画面にリダイレクトさせ、「登録失敗」のメッセージを表示させます。
try {
// トランザクション開始
DB::beginTransaction();
// リクエストされたデータをもとにeventsテーブルにデータをinsert
$insertEvent = $this->event->insertEventData($request);
// 処理に成功したらコミット
DB::commit();
} catch (\Throwable $e) {
// 処理に失敗したらロールバック
DB::rollback();
// エラーログ
\Log::error($e);
// 登録処理失敗時にリダイレクト
return redirect()->route('event.index')->with('error', 'もくもく会の登録に失敗しました。');
}
throw $e;で例外を投げていたのを、\Log::error($e);でエラーログを出すように修正しました。
また、失敗時のリダイレクトを書き、with関数を使ってビューにメッセージを渡しています。
フラッシュメッセージについては過去の記事で解説しているので、そちらをご参照ください。
\Log::error($e)とするとこで、src/storage/logs/laravel.logにエラーログが入ってきます。
{{-- フラッシュメッセージ --}}
{{-- 成功した時 --}}
@if (session('success'))
<div class="alert alert-success text-center">
{{ session('success') }}
</div>
@endif
{{-- 失敗した時 --}}
@if (session('error'))
<div class="alert alert-danger text-center">
{{ session('error') }}
</div>
@endif
@extends('layouts.app')
@section('content')
<style>
#mokumoku-lists {
filter:drop-shadow(2px 4px 6px #000);
}
.content-filed {
width: 60%;
}
</style>
{{-- もくもく会開催一覧リスト --}}
@foreach ($events as $event)
一覧画面にフラッシュメッセージ用のコードを追記します。
登録処理成功時
登録処理失敗時
これで登録処理については終わりです。
次回はバリデーションについて解説します。
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
コメント