Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Today, I will give you an example of “How to create Rating System in Laravel”, So you can easily apply it with your laravel 5, laravel 6, laravel 7, and laravel 8 application.
First, what we’re doing here, This is the example :
Review rating is the most common module in every application, mostly you will see the review and rating system in e-commerce platforms where there is an option after every product to rate or review by the user to share his experience or feedback.
For example, to implement a review and rating system in the laravel application we create and store some posts in the database and then implement a review and rating platform after every post, where the user can select stars rating and write his comment.
Let’s get started.
Generating Migration
We create new migration files for the “posts” and “review_ratings” table, In your cmd terminal hit the given below command.
php artisan make:migration create_posts_table
php artisan make:migration create_review_ratings_table
Migration Structures
Post Table Migration
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->longText('description');
$table->string('author');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}
Review Rating Table Migration
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateReviewRatingsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('review_ratings', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('post_id');
$table->string('name');
$table->string('email');
$table->string('phone');
$table->longText('comments')->nullable();
$table->integer('star_rating');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('review_ratings');
}
}
Run Migration
php artisan migrate
Posts Table :-
Review Ratings Table :-
Create Models
php artisan make:model Post
php artisan make:model ReviewRating
app\Models\Post.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
public function ReviewData()
{
return $this->hasMany('App\Models\ReviewRating','post_id');
}
}
Note :- Create a hasMany Relationship
We create a hasMany relationship in Post Model, we store post table (primary id) as a foreign key (post_id) in review_ratings table, whenever users will submit their own review or rate on each post.
public function ReviewData()
{
return $this->hasMany('App\Models\ReviewRating','post_id');
}
app\Models\ReviewRating.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class ReviewRating extends Model
{
use HasFactory;
}
Create a Controller
php artisan make:controller PostController
Define Web Routes
routes\web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;
/*
|--------------------------------------------------------------------------
| 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!
|
*/
#Manage Post
Route::get('/post-create',[PostController::class, 'create'])->name('post.create');
Route::post('/post-store',[PostController::class, 'store'])->name('post.store');
Route::get('/post-list',[PostController::class, 'list'])->name('post.list');
Route::get('/post-view/{id}',[PostController::class, 'view'])->name('post.view');
#Manage Review
Route::post('/review-store',[PostController::class, 'reviewstore'])->name('review.store');
app\Http\Controllers\PostController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Post;
use App\Models\ReviewRating;
use Session;
class PostController extends Controller
{
public function create()
{
return view('post.create');
}
public function store(Request $request){
$post = new Post();
$post->author = $request->author;
$post->title = $request->title;
$post->description = $request->description;
$post->save();
return redirect()->route('post.list');
}
public function list()
{
$posts = Post::orderBy('id','desc')->get();
return view('post.list',compact('posts'));
}
public function view($id){
$post_detail = Post::with('ReviewData')->find($id);
return view('post.view',compact('post_detail'));
}
public function reviewstore(Request $request){
$review = new ReviewRating();
$review->post_id = $request->post_id;
$review->name = $request->name;
$review->email = $request->email;
$review->phone = $request->phone;
$review->comments= $request->comment;
$review->star_rating = $request->rating;
$review->save();
return redirect()->back()->with('flash_msg_success','Your review has been submitted Successfully,');
}
}
Create Blade Files
Now, we make a post folder in views and then create these 3 files given below-:
resources\views\post\create.blade.php
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<style>
a {
color: #BE206B!important;
}
a.btn.btn-lg.btn-block,.btn-info {
color: white !important;
}
.btn-secondary {
background-color: #448BC6!important;
color: #fff!important;
}
button.btn.btn.btn-secondary {
width: 100%;
}
h3 {
text-align: center;
line-height: 200%;
}
.collpa
.pt-0, .py-0 {
padding-top: 0!important;
}
.rate {
float: left;
height: 46px;
padding: 0 10px;
}
.rate:not(:checked) > input {
position:absolute;
display: none;
}
.rate:not(:checked) > label {
float:right;
width:1em;
overflow:hidden;
white-space:nowrap;
cursor:pointer;
font-size:30px;
color:#ccc;
}
.rate:not(:checked) > label:before {
content: '★ ';
}
.rate > input:checked ~ label {
color: #ffc700;
}
.rate:not(:checked) > label:hover,
.rate:not(:checked) > label:hover ~ label {
color: #deb217;
}
.rate > input:checked + label:hover,
.rate > input:checked + label:hover ~ label,
.rate > input:checked ~ label:hover,
.rate > input:checked ~ label:hover ~ label,
.rate > label:hover ~ input:checked ~ label {
color: #c59b08;
}
.rating-container .form-control:hover, .rating-container .form-control:focus{
background: #fff;
border: 1px solid #ced4da;
}
.rating-container textarea:focus, .rating-container input:focus {
color: #000;
}
/* new page css */
</style>
</head>
<main>
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-6">
<div class="main">
<h3><a>Laravel 8 Review Rating System.</a></h3>
<form role="form" action="{{route('post.store')}}" method="post">
@csrf
<div class="form-group">
<label for="title">Post Title<span class="text-danger">*</span></label>
<input type="text" name="title" class="form-control" required>
</div>
<div class="form-group">
<label for="author">Post Author<span class="text-danger">*</span></label>
<input type="text" name="author" class="form-control" required>
</div>
<div class="form-group">
<label for="description">Post Description<span class="text-danger">*</span></label>
<input type="text" name="description" class="form-control" required>
</div>
<div class="form-group">
<button type="submit" class="btn btn btn-secondary">save</button>
</form>
</div>
</div>
</div>
</div>
</main>
</body>
</html>
resources\views\post\list.blade.php
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* {
box-sizing: border-box;
}
/* Add a gray background color with some padding */
body {
font-family: Arial;
padding: 20px;
background: #f1f1f1;
}
/* Header/Blog Title */
.header {
padding: 30px;
font-size: 40px;
text-align: center;
background: white;
}
/* Create two unequal columns that floats next to each other */
/* Left column */
.leftcolumn {
float: left;
width: 75%;
}
/* Right column */
.rightcolumn {
float: left;
width: 25%;
padding-left: 20px;
}
/* Fake image */
.fakeimg {
background-color: #aaa;
width: 100%;
padding: 20px;
}
/* Add a card effect for articles */
.card {
background-color: white;
padding: 20px;
margin-top: 20px;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
</style>
</head>
<body>
<div class="header">
<h2>Laravel 8 Review Rating System | 8bityard.com.</h2>
</div>
<div class="row">
<div class="leftcolumn">
@foreach($posts as $post)
<div class="card">
<h2 style="color:#0071a1;">{{ $post->title }}</h2>
<h5 style="color:#e91e63;">Published at : {{$post->created_at->format('jS \\of F Y') }}</h5>
<p>{{ $post->description }}</p>
<p><b><a href="{{route('post.view',$post->id)}}">Read Article</a></b></p>
</div>
@endforeach
</div>
<div class="rightcolumn">
<div class="card">
<h2>About Me</h2>
<img class="fakeimg" style="height:100px;" src="https://8bityard.com/ezoimgfmt/mllibnjakigh.i.optimole.com/e4PqOHU-NUmggukx/w:110/h:48/q:auto/https://8bityard.com/wp-content/uploads/2020/05/cropped-cropped-LogoMakr_48yknb-2.png?ezimgfmt=rs:110x48/rscb1/ng:webp/ngcb1">
<p>Laravel | WordPress | JQuery.</p>
</div>
</div>
</div>
</div>
</body>
</html>
Recommended Article :- Encrypt and Decrypt Id in Laravel.
resources\views\post\view.blade.php
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
* {
box-sizing: border-box;
}
/* Add a gray background color with some padding */
body {
font-family: Arial;
padding: 20px;
background: #f1f1f1;
}
/* Header/Blog Title */
.header {
padding: 30px;
font-size: 40px;
text-align: center;
background: white;
}
/* Create two unequal columns that floats next to each other */
/* Left column */
.leftcolumn {
float: left;
width: 75%;
}
/* Right column */
.rightcolumn {
float: left;
width: 25%;
padding-left: 20px;
}
/* Fake image */
.fakeimg {
background-color: #aaa;
width: 100%;
padding: 20px;
}
/* Add a card effect for articles */
.card {
background-color: white;
padding: 20px;
margin-top: 20px;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
.avatar {
vertical-align: middle;
width: 50px;
height: 50px;
border-radius: 50%;
}
.rate {
float: left;
height: 46px;
padding: 0 10px;
}
.rate:not(:checked) > input {
position:absolute;
display: none;
}
.rate:not(:checked) > label {
float:right;
width:1em;
overflow:hidden;
white-space:nowrap;
cursor:pointer;
font-size:30px;
color:#ccc;
}
.rate:not(:checked) > label:before {
content: '★ ';
}
.rate > input:checked ~ label {
color: #ffc700;
}
.rate:not(:checked) > label:hover,
.rate:not(:checked) > label:hover ~ label {
color: #deb217;
}
.rate > input:checked + label:hover,
.rate > input:checked + label:hover ~ label,
.rate > input:checked ~ label:hover,
.rate > input:checked ~ label:hover ~ label,
.rate > label:hover ~ input:checked ~ label {
color: #c59b08;
}
.rating-container .form-control:hover, .rating-container .form-control:focus{
background: #fff;
border: 1px solid #ced4da;
}
.rating-container textarea:focus, .rating-container input:focus {
color: #000;
}
/* End */
</style>
</head>
<body>
<div class="header">
<h2>Laravel 8 Review Rating System | 8bityard.com.</h2>
</div>
<div class="row">
<div class="leftcolumn">
<div class="card">
<h2 style="color:#0071a1;">{{ $post_detail->title }}</h2>
<p style="color:#e91e63;">Published at : {{$post_detail->created_at->format('jS \\of F Y') }}</p>
<p>{{ $post_detail->description }}</p>
<hr>
<!-- Display review section start -->
<div data-spy="scroll" data-target="#navbar-example2" data-offset="0">
<div>
<div class="row mt-5">
<h4>Comment Section :</h4>
<div class="col-sm-12 mt-5">
@foreach($post_detail->ReviewData as $review)
<div class=" review-content">
<img src="https://www.w3schools.com/howto/img_avatar.png" class="avatar ">
<span class="font-weight-bold ml-2">{{$review->name}}</span>
<p class="mt-1">
@for($i=1; $i<=$review->star_rating; $i++)
<span><i class="fa fa-star text-warning"></i></span>
@endfor
<span class="font ml-2">{{$review->email}}</span>
</p>
<p class="description ">
{{$review->comments}}
</p>
</div>
<hr>
@endforeach
</div>
</div>
</div>
</div>
<!-- Review store Section -->
<div class="container">
<div class="row">
<div class="col-sm-10 mt-4 ">
<form class="py-2 px-4" action="{{route('review.store')}}" style="box-shadow: 0 0 10px 0 #ddd;" method="POST" autocomplete="off">
@csrf
<input type="hidden" name="post_id" value="{{$post_detail->id}}">
<div class="row justify-content-end mb-1">
<div class="col-sm-8 float-right">
@if(Session::has('flash_msg_success'))
<div class="alert alert-success alert-dismissible p-2">
<a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>
<strong>Success!</strong> {!! session('flash_msg_success')!!}.
</div>
@endif
</div>
</div>
<p class="font-weight-bold ">Review</p>
<div class="form-group row">
<div class=" col-sm-6">
<input class="form-control" type="text" name="name" placeholder="Name" maxlength="40" required/>
</div>
<div class="col-sm-6">
<input class="form-control" type="email" name="email" placeholder="Email" maxlength="80" required/>
</div>
</div>
<div class="form-group row">
<div class="col-sm-6">
<input class="form-control" type="text" name="phone" placeholder="Phone" maxlength="40" required/>
</div>
<div class="col-sm-6">
<div class="rate">
<input type="radio" id="star5" class="rate" name="rating" value="5"/>
<label for="star5" title="text">5 stars</label>
<input type="radio" checked id="star4" class="rate" name="rating" value="4"/>
<label for="star4" title="text">4 stars</label>
<input type="radio" id="star3" class="rate" name="rating" value="3"/>
<label for="star3" title="text">3 stars</label>
<input type="radio" id="star2" class="rate" name="rating" value="2">
<label for="star2" title="text">2 stars</label>
<input type="radio" id="star1" class="rate" name="rating" value="1"/>
<label for="star1" title="text">1 star</label>
</div>
</div>
</div>
<div class="form-group row mt-4">
<div class="col-sm-12 ">
<textarea class="form-control" name="comment" rows="6 " placeholder="Comment" maxlength="200"></textarea>
</div>
</div>
<div class="mt-3 ">
<button class="btn btn-sm py-2 px-3 btn-info">Submit
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<div class="rightcolumn">
<div class="card">
<h2>About Me</h2>
<img class="fakeimg" style="height:100px;" src="https://8bityard.com/ezoimgfmt/mllibnjakigh.i.optimole.com/e4PqOHU-NUmggukx/w:110/h:48/q:auto/https://8bityard.com/wp-content/uploads/2020/05/cropped-cropped-LogoMakr_48yknb-2.png?ezimgfmt=rs:110x48/rscb1/ng:webp/ngcb1">
<p>Laravel | WordPress | JQuery.</p>
</div>
</div>
</div>
</body>
</html>
Note : We store post-primary ID as hidden in review_ratings table as a post_id (foreign_key) to get all related reviews and comments.
<input type="hidden" name="post_id" value="{{$post_detail->id}}">
Run Application :
127.0.0.1:8000/post-list
In this article, we successfully integrated “Laravel Review and Rating System Example”, I hope this article will help you with your Laravel application Project.