Laravel Comment System (ok)

https://www.mywebtuts.com/blog/laravel-8-comment-system-example-tutorial

C:\xampp\htdocs\reset\routes\web.php

<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;
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 within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
    return view('welcome');
});
Route::resource('posts', PostController::class);
Route::post('comments', [CommentController::class, 'store'])->name('comments.store');
Auth::routes();
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');

C:\xampp\htdocs\reset\app\Http\Controllers\PostController.php

<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller {
  /**
   * Write Your Code..
   *
   * @return string
   */
  public function index() {
    $posts = Post::get();
    return view('post.index', compact('posts'));
  }
  /**
   * Write Your Code..
   *
   * @return string
   */
  public function create() {
    return view('post.create');
  }
  /**
   * Write Your Code..
   *
   * @return string
   */
  public function store(Request $request) {
    $input = $request->all();
    $request->validate([
      'title' => 'required',
      'body'  => 'required',
    ]);
    Post::create($input);
    return redirect()->route('posts.index');
  }
  /**
   * Write Your Code..
   *
   * @return string
   */
  public function show($id) {
    $post = Post::find($id);
    return view('post.show', compact('post'));
  }
}

C:\xampp\htdocs\reset\app\Http\Controllers\CommentController.php

<?php
namespace App\Http\Controllers;
use App\Models\Comment;
use Illuminate\Http\Request;
class CommentController extends Controller {
  /**
   * Write Your Code..
   *
   * @return string
   */
  public function store(Request $request) {
    $input = $request->all();
    $request->validate([
      'body' => 'required',
    ]);
    $input['user_id'] = auth()->user()->id;
    Comment::create($input);
    return back();
  }
}

C:\xampp\htdocs\reset\resources\views\post\index.blade.php

@extends('layouts.app')
@section('content')
<div class="container">
  <div class="row justify-content-center">
    <div class="col-md-12">
      <h4>Manage Posts</h4>
      <a href="{{ route('posts.create') }}" class="btn btn-success btn-sm mb-2" style="float: right"><i class="fas fa-plus"></i>Create</a>
      <table class="table table-bordered table-hover">
        <thead>
          <th width="80px">Id</th>
          <th>Title</th>
          <th width="150px">Action</th>
        </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 btn-sm"><i class="fas fa-eye"></i>View</a>
          </td>
        </tr>
        @endforeach
        </tbody>
      </table>
    </div>
  </div>
</div>
@endsection

C:\xampp\htdocs\reset\resources\views\post\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-primary">MyWebtuts.com</h3>
          <hr />
          <br/>
          <h3>{{ $post->title }}</h3>
          <p>
            {{ $post->body }}
          </p>
          <hr />
          <h4>Display Comments</h4>
          <hr />
          @include('post.commentsDisplay', ['comments' => $post->comments, 'post_id' => $post->id])
          <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-primary" value="Add Comment" />
            </div>
          </form>
        </div>
      </div>
    </div>
  </div>
</div>
@endsection

C:\xampp\htdocs\reset\resources\views\post\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>
    <a href="" id="reply"></a>
    <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-success" value="Reply" />
      </div>
      <hr />
    </form>
    @include('post.commentsDisplay', ['comments' => $comment->replies])
  </div>
@endforeach

C:\xampp\htdocs\reset\resources\views\post\create.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-header">
          <h4>Create Post</h4>
        </div>
        <div class="card-body">
          <form method="post" action="{{ route('posts.store') }}">
            <div class="form-group">
              @csrf
              <label class="label">Post Title: </label>
              <input type="text" name="title" class="form-control" required/>
            </div>
            <div class="form-group">
              <label class="label">Post Body: </label>
              <textarea name="body" rows="4" cols="30" class="form-control" required></textarea>
            </div>
            <div class="form-group text-center">
              <input type="submit" class="btn btn-success" />
            </div>
          </form>
        </div>
      </div>
    </div>
  </div>
</div>
@endsection

C:\xampp\htdocs\reset\app\Http\Controllers\UserController.php

<?php
namespace App\Http\Controllers;
use App\Models\User;
class UserController extends Controller {
  /**
   * The application's index
   *
   * @var array
   */
  public function index() {
    $users = User::where('id', 1)->get();
    $users = User::where('id', 5)->get();
    $users = User::get();
    return view('users', compact('users'));
  }
}

C:\xampp\htdocs\reset\database\migrations\2022_05_14_221257_create_posts_comments_table.php

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePostsCommentsTable extends Migration {
  /**
   * Run the migrations.
   *
   * @return void
   */
  public function up() {
    Schema::create('posts', function (Blueprint $table) {
      $table->increments('id');
      $table->string('title');
      $table->text('body');
      $table->timestamps();
      $table->softDeletes();
    });
    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();
    });
  }
  /**
   * Reverse the migrations.
   *
   * @return void
   */
  public function down() {
    Schema::dropIfExists('posts');
    Schema::dropIfExists('comments');
  }
}

C:\xampp\htdocs\reset\app\Models\Post.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Post extends Model {
  use HasFactory, SoftDeletes;
  protected $dates = ['deleted_at'];
  /**
   * The attributes that are mass assignable.
   *
   * @var array
   */
  protected $fillable = ['title', 'body'];
  /**
   * Write Your Code..
   *
   * @return string
   */
  public function comments() {
    return $this->hasMany(Comment::class)->whereNull('parent_id');
  }
}

C:\xampp\htdocs\reset\app\Models\Comment.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Comment extends Model {
  use HasFactory, SoftDeletes;
  protected $dates = ['deleted_at'];
  /**
   * The attributes that are mass assignable.
   *
   * @var array
   */
  protected $fillable = ['user_id', 'post_id', 'parent_id', 'body'];
  /**
   * Write Your Code..
   *
   * @return string
   */
  public function user() {
    return $this->belongsTo(User::class);
  }
  /**
   * Write Your Code..
   *
   * @return string
   */
  public function replies() {
    return $this->hasMany(Comment::class, 'parent_id');
  }
}

Hi Artisan,

In this Article I will share something new about how actually work a comment system with laravel 8. I will create a custom comment system in laravel 8. so how to integrate custom nested comments using relationship in laravel 8.

First of all i will exaplain previous example how to create simple authentication using laravel-ui you will learn this first follow this article laravel-8-authentication-tutorial

So, in this example I will create two tables for one is posts and another is comments using the migration command.

Here,i will give you a simple and easy example how to use implement comment system in laravel 8 in laravel simply follow my all steps.

Step 1 : Install Laravel App

In this step, You can install laravel fresh app. So open the terminal and put the bellow command.

composer create-project --prefer-dist laravel/laravel commentSystem

Step 2 : Setup Database Configuration

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=Enter_Your_Database_Name
DB_USERNAME=Enter_Your_Database_Username
DB_PASSWORD=Enter_Your_Database_Password

Step 3 : Create Post and Comment Table

In this third step we have to integrate two tables using create migration for "posts" and "comments" table.

Path : /database/migrations/2021_09_20_130819_create_posts_comments_table.php

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostsCommentsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->text('body');
            $table->timestamps();
            $table->softDeletes();
        });

        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();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
        Schema::dropIfExists('comments');
    }
}

Now we need to run migration be bellow command:

php artisan migrate

Step 4 : Create Auth using scaffold

Now, in this step, we will create auth scaffold command to create login, register and dashboard. so run following commands:

composer require laravel/ui

Using Bootstrap:

php artisan ui bootstrap --auth

Step 5 : Create Model

In this step i will create a Post model using following command.

php artisan make:model Post
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Post extends Model
{
    use HasFactory, SoftDeletes;

    protected $dates = ['deleted_at'];
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['title', 'body'];

    /**
     * Write Your Code..
     *
     * @return string
    */
    public function comments()
    {
        return $this->hasMany(Comment::class)->whereNull('parent_id');
    }
}

Run bellow command for Comment model:

php artisan make:model Comment
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Comment extends Model
{
    use HasFactory, SoftDeletes;

    protected $dates = ['deleted_at'];

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['user_id', 'post_id', 'parent_id', 'body'];

    /**
     * Write Your Code..
     *
     * @return string
    */
    public function user()
    {
        return $this->belongsTo(User::class);
    }

    /**
     * Write Your Code..
     *
     * @return string
    */
    public function replies()
    {
        return $this->hasMany(Comment::class, 'parent_id');
    }
}

Step 6 : Create Route

now, we require to create a route for HomeController in laravel application. so open your "routes/web.php" file and add the following route.

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;
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 within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::resource('posts', PostController::class);
Route::post('comments', [CommentController::class, 'store'])->name('comments.store');

Step 7 : Create Controller

php artisan make:controller PostController
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Post;
use App\Models\Comment;

class PostController extends Controller
{
    /**
     * Write Your Code..
     *
     * @return string
    */
    public function index()
    {
        $posts = Post::get();

        return view('post.index',compact('posts'));

    }

    /**
     * Write Your Code..
     *
     * @return string
    */
    public function create()
    {
        return view('post.create');
    }

    /**
     * Write Your Code..
     *
     * @return string
    */
    public function store(Request $request)
    {
        $input = $request->all();
        $request->validate([
            'title' => 'required',
            'body' => 'required',
        ]);

        Post::create($input);

        return redirect()->route('posts.index');
    }

    /**
     * Write Your Code..
     *
     * @return string
    */
    public function show($id)
    {
        $post = Post::find($id);

        return view('post.show',compact('post'));
    }

}

Create CommentController using bellow command:

php artisan make:controller CommentController
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Comment;

class CommentController extends Controller
{
    /**
     * Write Your Code..
     *
     * @return string
    */
    public function store(Request $request)
    {
        $input = $request->all();

        $request->validate([
            'body'=>'required',
        ]);

        $input['user_id'] = auth()->user()->id;

        Comment::create($input);

        return back();
    }
}

Step 8 : Create Blade File

In this step we have to create a blade file. So finally you have to create the following file and put bellow code:

  • index.blade.php

  • create.blade.php

  • show.blade.php

  • commentsDisplay.blade.php

Path : /resources/views/post/index.blade.php

@extends('layouts.app')
   
@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-12">
            <h4>Manage Posts</h4>
            <a href="{{ route('posts.create') }}" class="btn btn-success btn-sm mb-2" style="float: right"><i class="fas fa-plus"></i></a>
            <table class="table table-bordered table-hover">
                <thead>
                    <th width="80px">Id</th>
                    <th>Title</th>
                    <th width="150px">Action</th>
                </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 btn-sm"><i class="fas fa-eye"></i></a>
                    </td>
                </tr>
                @endforeach
                </tbody>
   
            </table>
        </div>
    </div>
</div>
@endsection

Path : /resources/views/post/create.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-header">
                    <h4>Create Post</h4>
                </div>
                <div class="card-body">
                    <form method="post" action="{{ route('posts.store') }}">
                        <div class="form-group">
                            @csrf
                            <label class="label">Post Title: </label>
                            <input type="text" name="title" class="form-control" required/>
                        </div>
                        <div class="form-group">
                            <label class="label">Post Body: </label>
                            <textarea name="body" rows="4" cols="30" class="form-control" required></textarea>
                        </div>
                        <div class="form-group text-center">
                            <input type="submit" class="btn btn-success" />
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

Path : /resources/views/post/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-primary">MyWebtuts.com</h3>
                    <hr />
                    <br/>
                    <h3>{{ $post->title }}</h3>
                    <p>
                        {{ $post->body }}
                    </p>
                    <hr />
                    <h4>Display Comments</h4>
  
                    <hr />
                    @include('post.commentsDisplay', ['comments' => $post->comments, 'post_id' => $post->id])
   
                    <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-primary" value="Add Comment" />
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

Path : /resources/views/post/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>
        <a href="" id="reply"></a>
        <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-success" value="Reply" />
            </div>
            <hr />
        </form>
        @include('post.commentsDisplay', ['comments' => $comment->replies])
    </div>
@endforeach

Now we are ready to run our example so run bellow command for quick run:

http://localhost:8000/posts

Post Page

Comment Page

Last updated