Using this Laravel 11 Comment Reply System Tutorial you will learn how to build a comment and reply system in a Laravel application. In a Laravel 11 application, setting up a comment and reply system is straightforward with Eloquent relationships. Let’s see the step by step guide:
Step 1 – Create Post and Comment Migration Files
Execute these commands to generate migration files for posts and comments, along with their models:
php artisan make:model Post -m
php artisan make:model Comment -m
Modify the database/migrations/posts.php
file to include:
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->text('body');
$table->timestamps();
$table->softDeletes();
});
Update the database/migrations/comments.php
file with:
Schema::create('comments', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('post_id')->unsigned();
$table->integer('parent_id')->unsigned()->nullable();
$table->text('body');
$table->timestamps();
$table->softDeletes();
});
Step 2 – Define Relationships Between Tables
Edit the app/Models/Post.php
file to set up the relationship with comments:
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Post extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
protected $fillable = ['title', 'body'];
public function comments()
{
return $this->hasMany(Comment::class)->whereNull('parent_id');
}
}
Update the app/Models/Comment.php
file to define its relationships with users and other comments:
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Comment extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
protected $fillable = ['user_id', 'post_id', 'parent_id', 'body'];
public function user()
{
return $this->belongsTo(User::class);
}
public function replies()
{
return $this->hasMany(Comment::class, 'parent_id');
}
}
Step 3 – Set Up Bootstrap Authentication
Install Laravel UI for authentication scaffolding:
composer require laravel/ui
Generate the authentication system using Bootstrap:
php artisan ui bootstrap --auth
Compile the Bootstrap assets:
npm install
npm run dev
Step 4 – Create Controllers
Generate a controller for posts:
php artisan make:controller PostController
Edit the app/Http/Controllers/PostController.php
file to include:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Post;
class PostController extends Controller
{
public function index()
{
$posts = Post::all();
return view('posts.index', compact('posts'));
}
public function show($id)
{
$post = Post::find($id);
return view('posts.show', compact('post'));
}
}
Generate a controller for comments:
php artisan make:controller CommentController
Edit the app/Http/Controllers/CommentController.php
file to add:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Comment;
class CommentController extends Controller
{
public function store(Request $request)
{
$request->validate([
'body' => 'required',
]);
$input = $request->all();
$input['user_id'] = auth()->user()->id;
Comment::create($input);
return back();
}
}
Step 5 – Define Routes
Update the routes/web.php
file to include:
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;
use App\Http\Controllers\CommentController;
Route::get('/posts', [PostController::class, 'index'])->name('posts.index');
Route::get('/posts/{id}', [PostController::class, 'show'])->name('posts.show');
Route::post('/comments', [CommentController::class, 'store'])->name('comments.store');
Step 6 – Create Views
In the resources/views
directory, create views to display posts, comment forms, and comments.
Create index.blade.php
:
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-12">
<h1>Post List</h1>
<a href="{{ route('posts.create') }}" class="btn btn-success" style="float: right">Create Post</a>
<table class="table table-bordered">
<thead>
<tr>
<th width="80px">Id</th>
<th>Title</th>
<th width="150px">Action</th>
</tr>
</thead>
<tbody>
@foreach($posts as $post)
<tr>
<td>{{ $post->id }}</td>
<td>{{ $post->title }}</td>
<td>
<a href="{{ route('posts.show', $post->id) }}" class="btn btn-primary">View Post</a>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
@endsection
Create show.blade.php
:
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-body">
<h3 class="text-center text-success">Details</h3>
<br/>
<h2>{{ $post->title }}</h2>
<p>{{ $post->body }}</p>
<hr />
<h4>Display Comments</h4>
@include('posts.commentsDisplay', ['comments' => $post->comments, 'post_id' => $post->id])
<hr />
<h4>Add comment</h4>
<form method="post" action="{{ route('comments.store') }}">
@csrf
<div class="form-group">
<textarea class="form-control" name="body"></textarea>
<input type="hidden" name="post_id" value="{{ $post->id }}" />
</div>
<div class="form-group">
<input type="submit" class="btn btn-success" value="Add Comment" />
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
Create commentsDisplay.blade.php
:
@foreach($comments as $comment)
<div class="display-comment" @if($comment->parent_id != null) style="margin-left:40px;" @endif>
<strong>{{ $comment->user->name }}</strong>
<p>{{ $comment->body }}</p>
<form method="post" action="{{ route('comments.store') }}">
@csrf
<div class="form-group">
<input type="text" name="body" class="form-control" />
<input type="hidden" name="post_id" value="{{ $post_id }}" />
<input type="hidden" name="parent_id" value="{{ $comment->id }}" />
</div>
<div class="form-group">
<input type="submit" class="btn btn-warning" value="Reply" />
</div>
</form>
@include('posts.commentsDisplay', ['comments' => $comment->replies])
</div>
@endforeach
Step 7 – Test Your Application
Start the Laravel development server:
php artisan serve
Visit http://localhost:8000/posts
in your browser to test the application.