コメントを削除する場合も投稿者でなければ許可されないようにします.また,削除ボタンを押してそのまま削除されるのではなく,一旦確認画面を表示して,さらにボタンを押してはじめて削除されるようにします.
まずルート情報を定義します.
routes/web.php
<?php
use App\Http\Controllers\ProfileController;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\CommentController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "web" middleware group. Make something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware(['auth', 'verified'])->name('dashboard');
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');
});
// 'verified' を 'auth' と一緒に利用することでメール認証後にしかログインできなくなる
Route::middleware('auth', 'verified')->group(function () {
Route::get('/comments', [CommentController::class, 'index'])->name('comments.index');
Route::get('/comments/create', [CommentController::class, 'create'])->name('comments.create');
Route::get('/comments/{comment_id}', [CommentController::class, 'show'])->name('comments.show');
Route::get('/comments/{comment_id}/edit', [CommentController::class, 'edit'])->name('comments.edit');
Route::get('/comments/{comment_id}/delete', [CommentController::class, 'delete'])->name('comments.delete');
Route::post('/comments', [CommentController::class, 'store'])->name('comments.store');
Route::patch('/comments', [CommentController::class, 'update'])->name('comments.update');
Route::delete('/comments', [CommentController::class, 'destroy'])->name('comments.destroy');
});
require __DIR__.'/auth.php';
詳細表示のビューに削除のためのリンクを設置します.ただし編集の時と同様に削除のリンクも投稿者のみに表示するようにします.
resources/views/comments/show.blade.php
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Comment') }}
</h2>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 text-gray-900">
<div class="my-2 border border-gray-300 rounded-md p-3">
<div class="text-sm text-gray-700">Owner:</div>
<div class="text-base text-gray-800 indent-4">{{ $comment->user->name }}</div>
<div class="text-sm text-gray-700">Title:</div>
<div class="text-lg font-semibold text-gray-800 indent-4">{{ $comment->title }}</div>
<div class="text-sm text-gray-700">Body:</div>
<div class="text-base text-gray-800 indent-4">{{ $comment->body }}</div>
<div class="text-xs text-gray-600 pt-4">Created_at: {{ $comment->created_at }} / Updated_at: {{ $comment->updated_at }}</div>
@if ($comment->user_id == $user->id)
<hr class="my-2">
<div class="text-sm">
<a href="{{ route('comments.edit', $comment->id) }}" class="text-blue-500 hover:text-blue-800 hover:underline active:text-blue-900 active:bg-gray-200 transition ease-in-out duration-150">
コメントの編集
</a>
<a href="{{ route('comments.delete', $comment->id) }}" class="text-blue-500 hover:text-blue-800 hover:underline active:text-blue-900 active:bg-gray-200 transition ease-in-out duration-150 ml-5">
コメントの削除
</a>
</div>
@endif
</div>
</div>
</div>
</div>
</div>
</x-app-layout>
コントローラに delete
と destroy
関数を定義します.ここで delete
関数はその大半が edit
関数と同じです.
app/Http/Controllers/CommentController.php(抜粋)
public function delete($comment_id)
{
$comment = Comment::where('id', '=', $comment_id)
->first();
if (!$comment) {
return redirect('/comments');
}
$user = Auth::user();
if ($comment->user_id != $user->id) {
return redirect('/comments');
}
return view('comments.delete')
->with('comment', $comment)
->with('user', $user);
}
public function destroy(Request $request)
{
dd($request);
}
削除の確認ページを作成します.
resources/views/comments/delete.blade.php
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Delete Comment') }}
</h2>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 text-gray-900">
<div class="my-2 border border-gray-300 rounded-md p-3">
<div class="text-sm text-gray-700">Owner:</div>
<div class="text-base text-gray-800 indent-4">{{ $comment->user->name }}</div>
<div class="text-sm text-gray-700">Title:</div>
<div class="text-base text-gray-800 indent-4">{{ $comment->title }}</div>
<div class="text-sm text-gray-700">Body:</div>
<div class="text-base text-gray-800 indent-4">{{ $comment->body }}</div>
<div class="text-xs text-gray-600 pt-4">Created_at: {{ $comment->created_at }} / Updated_at: {{ $comment->updated_at }}</div>
<hr class="mt-3 mb-3">
<div class="text-xl font-bold text-red-800">本当に削除しますか?</div>
<form method="POST" action="{{ route('comments.destroy') }}">
@csrf
{{ method_field('delete') }}
<input type="hidden" name="comment_id" value="{{ $comment->id }}">
<input type="hidden" name="user_id" value="{{ $user->id }}">
<x-primary-button class="block mt-2 bg-red-600 hover:bg-red-200 focus:bg-red-200 active:bg-red-400">
{{ __('コメントの削除') }}
</x-primary-button>
</form>
</div>
</div>
</div>
</div>
</div>
</x-app-layout>
削除したいコメントを表示して「コメントの削除」リンクをクリックします.
そのまま削除されるわけではなく,一旦確認のページが表示されます.
ボタンにマウスがポイントされた状態のデザインがスタイリングされています.
ボタンを押している最中の状態のデザインもスタイリングされています.
削除ボタンを押した時にフォームから送信された内容が確認できます.
この確認ができれば実際に destroy
関数にコメントを削除する機能を実装します.
app/Http/Controllers/CommentController.php(抜粋)
public function destroy(Request $request)
{
$comment = Comment::where('id', '=', $request->comment_id)
->first();
if (!$comment) {
return redirect('/comments');
}
$user = Auth::user();
if ($request->user_id != $user->id) {
return redirect('/comments');
}
$comment->delete();
return redirect('/comments');
}
先頭に表示されていたコメントが削除されました.