すでにデータベースに格納された投稿内容を編集する機能を実装します.次のような手順で作業を行います.
まず編集と更新のためのルートを定義します.なお,編集ページの表示は get メソッドですが,更新は patch メソッドであることに注意してください.
routes/web.php(抜粋)
Route::get('/comments', [CommentsController::class, 'index']) -> name('comments.index');
Route::get('/comments/{comment_id}', [CommentsController::class, 'show']) -> name('comments.show');
Route::get('/comments/{comment_id}/edit', [CommentsController::class, 'edit']) -> name('comments.edit');
Route::post('/comments', [CommentsController::class, 'store']) -> name('comments.store');
Route::patch('/comments', [CommentsController::class, 'update']) -> name('comments.update');
次に詳細ページのビューに編集ページへのリンクを設置します.show.blade.php を次のように編集します.
resources/views/comments/show.blade.php(抜粋)
<body>
<h1>コメント</h1>
<dl>
<dt>ID:</dt>
<dd>{{ $comment->id }}</dd>
<dt>Title:</dt>
<dd>{{ $comment->title }}</dd>
<dt>Body:</dt>
<dd>{{ $comment->body }}</dd>
</dl>
<p>
<a href="{{ route('comments.edit', ['comment_id' => $comment->id]) }}">
[編集]
</a>
</p>
</body>
CommentsController に edit メソッドを準備します.このメソッドの内容の大半は show 関数と同じです.
app/HTTP/Controllers/CommentsController.php(抜粋)
public function edit($comment_id)
{
$comment = Comment::where('id', '=', $comment_id)
->first();
if (!$comment) {
return redirect('/comments');
}
return view('comments.edit') // show 関数との違いはここだけ
->with('comment', $comment);
}
続いて,編集のための edit.blade.php を新規に作成します.もちろん show.blade.php などをコピーして適宜編集すると良いでしょう.なお,更新フォームのリクエストリクエストメソッドには PATCH を使い,GET でも POST でもありません.10行目で PATCH は指定できないので,ここは POST にしておき,12行目に @method('PATCH')
を使ってリクエストメソッドを変更します.またセキュリティ確保のための @csrf
の指定も忘れないようにしてください.また,13行目にはコメントの ID を指定するための隠し込むおくを hidden 属性で指定しているとともに,フォームにはデータベースから取得した文字列をあらかじめ表示しておくためのコードを16行目と23行目に追加していることにも注意してください.
resources/views/comments/edit.blade.php(抜粋)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>コメント編集</title>
</head>
<body>
<h1>コメント編集</h1>
<div>
<form method="post" action="{{ route('comments.update') }}" enctype='multipart/form-data'>
@csrf
@method('PATCH')
<input type="hidden" name="comment_id" value="{{ $comment->id }}">
<p>
<label for="title">Title: </label>
<input type="text" name="title" id="title" value="{{ $comment->title }}{{ old('title') }}">
@if ($errors->has('title'))
<span class="error">{{ $errors->first('title') }}</span>
@endif
</p>
<p>
<label for="body">Body: </label>
<textarea name="body" id="body" rows="4" cols="50">{{ $comment->body }}{{ old('body') }}</textarea>
@if ($errors->has('body'))
<span class="error">{{ $errors->first('body') }}</span>
@endif
</p>
<p>
<input type="submit" value="更新">
</p>
</form>
</div>
</body>
</html>
さらに投稿の更新作業を行う update 関数をコントローラに追加します.まずは dd()
を使って,リクエスト内容を表示します.
app/HTTP/Controllers/CommentsController.php(抜粋)
public function update(Request $request)
{
dd($request);
}
2個目のコメントの内容を変更して更新ボタンを押した結果は次のようになります.
最後にコントローラの update 関数に更新処理を記載します.更新の際も入力内容の検証を行うと良いでしょう.
app/HTTP/Controllers/CommentsController.php(抜粋)
public function update(Request $request)
{
$this->validate($request, [
'title' => 'required|max:10', // 入力が必須で,最大10文字
'body' => 'required' // 入力が必須
]);
$comment = Comment::where('id', '=', $request->comment_id)
->first();
if (!$comment) {
return redirect('/comments');
}
$comment->title = $request->title;
$comment->body = $request->body;
$comment->save();
return redirect()->route('comments.show', ['comment_id' => $comment->id]);
}
実際にコメントを更新した結果です.