Comments System
LaravelLet's add a comments system where readers can leave comments on posts. Comments will require moderation (approval) before appearing publicly.
Comment Controller
app/Http/Controllers/CommentController.php
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use App\Models\Comment;
use Illuminate\Http\Request;
class CommentController extends Controller
{
public function store(Request $request, Post $post)
{
$validated = $request->validate([
'body' => 'required|string|min:5|max:1000',
'author_name' => 'required_if:guest,true|string|max:100',
'author_email' => 'required_if:guest,true|email|max:255',
]);
Comment::create([
'post_id' => $post->id,
'user_id' => auth()->id(),
'author_name' => auth()->check() ? null : $validated['author_name'],
'author_email' => auth()->check() ? null : $validated['author_email'],
'body' => $validated['body'],
'approved' => auth()->check(), // Auto-approve for logged-in users
]);
$message = auth()->check()
? 'Comment posted successfully!'
: 'Comment submitted! It will appear after moderation.';
return back()->with('success', $message);
}
}Comment Routes
routes/web.php
<?php
Route::post('/post/{post}/comments', [CommentController::class, 'store'])
->name('comments.store')
->middleware('throttle:5,1'); // Max 5 comments per minuteComments in Post View
resources/views/blog/show.blade.php (comments section)
<!-- Comments Section -->
<div class="mt-12">
<h3 class="text-xl font-bold mb-6">
{{ $post->approvedComments->count() }} Comments
</h3>
<!-- Comment List -->
@forelse($post->approvedComments as $comment)
<div class="flex gap-4 mb-6">
<div class="w-10 h-10 bg-blue-100 rounded-full flex items-center justify-center font-bold text-blue-600 flex-shrink-0">
{{ strtoupper(substr($comment->display_name, 0, 1)) }}
</div>
<div class="flex-1">
<div class="flex items-center gap-2 mb-1">
<strong>{{ $comment->display_name }}</strong>
<span class="text-gray-400 text-xs">{{ $comment->created_at->diffForHumans() }}</span>
</div>
<p class="text-gray-700">{{ $comment->body }}</p>
</div>
</div>
@empty
<p class="text-gray-400">No comments yet. Be the first!</p>
@endforelse
<!-- Comment Form -->
<div class="mt-8 bg-gray-50 rounded-lg p-6">
<h4 class="font-bold mb-4">Leave a Comment</h4>
@if(session('success'))
<div class="bg-green-100 text-green-700 p-3 rounded mb-4">{{ session('success') }}</div>
@endif
<form method="POST" action="{{ route('comments.store', $post) }}">
@csrf
@guest
<div class="grid grid-cols-2 gap-4 mb-4">
<div>
<label class="block text-sm font-medium mb-1">Name *</label>
<input type="text" name="author_name" class="w-full border rounded p-2"
value="{{ old('author_name') }}" required />
</div>
<div>
<label class="block text-sm font-medium mb-1">Email *</label>
<input type="email" name="author_email" class="w-full border rounded p-2"
value="{{ old('author_email') }}" required />
</div>
</div>
@endguest
<div class="mb-4">
<label class="block text-sm font-medium mb-1">Comment *</label>
<textarea name="body" rows="4" class="w-full border rounded p-2"
placeholder="Share your thoughts...">{{ old('body') }}</textarea>
@error('body')<p class="text-red-500 text-sm mt-1">{{ $message }}</p>@enderror
</div>
<button type="submit"
class="bg-blue-600 text-white px-6 py-2 rounded hover:bg-blue-700">
Post Comment
</button>
</form>
</div>
</div>Admin — Approve Comments
app/Http/Controllers/Admin/CommentController.php
<?php
class CommentController extends Controller
{
public function index()
{
$pending = Comment::where('approved', false)->with('post')->latest()->get();
$approved = Comment::where('approved', true)->with('post')->latest()->take(20)->get();
return view('admin.comments.index', compact('pending', 'approved'));
}
public function update(Comment $comment)
{
$comment->update(['approved' => true]);
return back()->with('success', 'Comment approved!');
}
public function destroy(Comment $comment)
{
$comment->delete();
return back()->with('success', 'Comment deleted!');
}
}💡
Always use throttle on comment forms!
->middleware('throttle:5,1') limits to 5 submissions per minute per IP. This prevents spam bots from flooding your blog with fake comments.Stuck? Need help?
Review the previous lessons or check the Laravel documentation.