Docker×Laravel8でもくもく会アプリを作成する更新処理編です。
前回の記事の続きになるので、まだの方は以下をご参照ください。
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
更新処理を実装するステップ
更新処理のルーティングを追加する
まずは更新処理用のルーティングを追加します。
// もくもく会更新処理
Route::post('event/update', [EventController::class, 'update'])
->name('event.update');
edit.blade.phpのルート先を修正する
route(‘event.create’)になっていると思うので、updateに修正します。
さらに、hiddenでevent_idを送信できるようにします。
updateアクションで、$request->event_idとすれば、eventsテーブルのevent_idを取得できますよ!
<div class="container">
<form action="{{ route('event.update') }}" method="POST">
@csrf
<input type="hidden" name="event_id" value="{{ $event->event_id }}">
edit.blade.phpの全体像
@extends('layouts.app')
@section('content')
<div class="container">
<form action="{{ route('event.update') }}" method="POST">
@csrf
<input type="hidden" name="event_id" value="{{ $event->event_id }}">
{{-- タイトルフォーム --}}
<div class="form-group">
<label for="title">{{ 'タイトル' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<input type="text" class="form-control{{ $errors->has('title') ? ' is-invalid' : '' }}" name="title" id="title" value="{{ old('title', $event->title) }}">
@if ($errors->has('title'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('title') }}
</span>
@endif
</div>
{{-- カテゴリープルダウン --}}
<div class="form-group w-50">
<label for="category-id">{{ 'カテゴリー' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<select class="form-control{{ $errors->has('category_id') ? ' is-invalid' : '' }}" id="category-id" name="category_id">
@foreach ($categories as $category)
@if (!is_null(old('category_id')))
{{-- バリデーション時の挙動 --}}
@if (old('category_id') == $category->category_id)
<option value="{{ $category->category_id }}" selected>{{ $category->category_name }}</option>
@else
<option value="{{ $category->category_id }}">{{ $category->category_name }}</option>
@endif
@else
{{-- 初期表示 --}}
@if ($event->category_id == $category->category_id))
<option value="{{ $category->category_id }}" selected>{{ $category->category_name }}</option>
@else
<option value="{{ $category->category_id }}">{{ $category->category_name }}</option>
@endif
@endif
@endforeach
</select>
@if ($errors->has('category_id'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('category_id') }}
</span>
@endif
</div>
{{-- 開催日をカレンダーで選択 --}}
<div class="form-group w-25">
<label for="date">{{ '開催日' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<input type="date" class="form-control{{ $errors->has('date') ? ' is-invalid' : '' }}" name="date" id="date" value="{{ old('date', $event->date) }}">
@if ($errors->has('date'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('date') }}
</span>
@endif
</div>
{{-- もくもく会開催時間 --}}
<div class="form-group w-50">
<div class="row">
{{-- 開始時間 --}}
<div class="col">
<label for="start_time">{{ '開始時間' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<input type="time" class="form-control{{ $errors->has('start_time') ? ' is-invalid' : '' }}" name="start_time" id="start_time" value="{{ old('start_time', $event->start_time) }}">
@if ($errors->has('start_time'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('start_time') }}
</span>
@endif
</div>
{{-- 終了時間 --}}
<div class="col">
<label for="end_time">{{ '終了時間' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<input type="time" class="form-control{{ $errors->has('end_time') ? ' is-invalid' : '' }}" name="end_time" id="end_time" value="{{ old('end_time', $event->end_time) }}">
@if ($errors->has('end_time'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('end_time') }}
</span>
@endif
</div>
</div>
</div>
{{-- 参加費フォーム --}}
<div class="form-group w-25">
<label for="entry-fee">{{ '参加費' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<input type="text" class="form-control{{ $errors->has('entry_fee') ? ' is-invalid' : '' }}" name="entry_fee" id="entry-fee" value="{{ old('entry_fee', $event->entry_fee) }}">
@if ($errors->has('entry_fee'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('entry_fee') }}
</span>
@endif
</div>
{{-- もくもく会の詳細 --}}
<div class="form-group">
<label for="content">{{ '詳細' }}<span class="badge badge-danger ml-2">{{ '必須' }}</span></label>
<textarea class="form-control{{ $errors->has('content') ? ' is-invalid' : '' }}" name="content" id="content" rows="10" placeholder="もくもく会の詳細を記載してください。">{{ old('content', $event->content) }}</textarea>
@if ($errors->has('content'))
<span class="invalid-feedback" role="alert">
{{ $errors->first('content') }}
</span>
@endif
</div>
<button type="submit" class="btn btn-success w-100">
{{ 'もくもく会を更新する' }}
</button>
</form>
</div>
@endsection
コントローラーにupdateのアクションを追加する
次にEventControllerにupdateアクションを追加します。
/**
* 更新処理
*/
public function update(Request $request)
{
return redirect()->route('event.index')->with('success', 'もくもく会の更新に成功しました。');
}
これで一応、編集画面から更新ボタンを押すとフラッシュメッセージとともに一覧画面に遷移できます。
/**
* 更新処理
*/
public function update(Request $request)
{
// イベントIDを取得
$eventId = $request->event_id;
// イベントIDをもとに更新対象のレコードを1件取得
$event = $this->event->findEventByEventId($eventId);
// 更新対象のレコードの更新処理を実行
$isUpdated = $this->event->updatedEventData($request, $event);
return redirect()->route('event.index')->with('success', 'もくもく会の更新に成功しました。');
}
$eventIdでイベントIDを取得し、そのイベントIDをもとに更新対象のレコードを取得します。やってることは編集画面の時と同じです。
後ほどモデルに更新処理を書いていきますが、更新処理をまずは仮に$isupdatedと定義しておきましょう。
ここから本題の更新処理を書いていきます。
モデルに更新のロジックを書く
それでは、実際に更新処理をモデルに書いていきます。
更新処理にはfill…saveメソッドを使います。
<?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();
}
/**
* idをもとにeventsテーブルから特定のレコードに絞り込む
*
* @param int $id イベントID
* @return Event
*/
public function findEventByEventId($id)
{
return $this->find($id);
}
/**
* 登録処理 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,
]);
}
/**
* 更新処理
*/
public function updatedEventData($request, $event)
{
return $event->fill([
'category_id' => $request->category_id,
'title' => $request->title,
'date' => $request->date,
'start_time' => $request->start_time,
'end_time' => $request->end_time,
'entry_fee' => $request->entry_fee,
'content' => $request->content,
])->save();
}
}
登録処理と割と似ているところがありますが、違いとしては、更新対象のレコード$eventを使用していることやfill…saveですね。
更新処理にもバリデーションを適用させる
更新処理にも登録処理のようにバリデーションを適用させます。
public function update(EventRequest $request) // Request->EventRequestに修正
ここまでで、入力に誤りがあれば更新処理でもバリデーションが実行され、問題なければデータが更新されます。
try…catchやトランザクションをつけておく
登録処理でもやりましたが、データの登録や更新には安全にデータを扱うためやデータの整合性を保つためにtry…catchやトランザクションをつけましょう。
/**
* 更新処理
*/
public function update(EventRequest $request)
{
// イベントIDを取得
$eventId = $request->event_id;
// イベントIDをもとに更新対象のレコードを1件取得
$event = $this->event->findEventByEventId($eventId);
try {
DB::beginTransaction();
// 更新対象のレコードの更新処理を実行
$isUpdated = $this->event->updatedEventData($request, $event);
// 処理に成功したらコミット
DB::commit();
} catch (\Throwable $e) {
// 処理に失敗したらロールバック
DB::rollback();
// エラーログ
\Log::error($e);
// 登録処理失敗時にリダイレクト
return redirect()->route('event.index')->with('error', 'もくもく会の更新に失敗しました。');
}
return redirect()->route('event.index')->with('success', 'もくもく会の更新に成功しました。');
}
これで更新処理は完成しました。
次回は、削除処理について解説します。
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
コメント