Laravel 8 E-Commerce - User Review & Rating on Product
In this video, we will learn about user reviews and ratings on products.
Let's explore how users can add reviews and ratings to products.
First, we need to create a model and migration for reviews.
Switch to the command prompt and run the following command:
php artisan make:model Review –m
Now, switch to the project and open the create_reviews_table
migration file. Add the following code:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateReviewsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('reviews', function (Blueprint $table) {
$table->id();
$table->integer('rating');
$table->text('comment');
$table->bigInteger('order_item_id')->unsigned();
$table->timestamps();
$table->foreign('order_item_id')->references('id')->on('order_items')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('reviews');
}
}
Next, we need to add a column to the OrderItems
table.
Switch to the command prompt and create a migration for adding a new column to the orderitems
table:
php artisan make:migration add_rstatus_to_order_items_table --table= order_items
Now, switch to the project and open the new migration file. Add the following code:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddRstatusToOrderItemsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('order_items', function (Blueprint $table) {
$table->boolean('rstatus')->default(false);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('order_items', function (Blueprint $table) {
$table->dropColumn('rstatus');
});
}
}
Now, let's migrate the migration.
Go to the command prompt and run the following command:
php artisan migrate
Run the application:
php artisan serve
Switch to the project and open the user-order-details.blade.php
component view file. Modify the code as follows in the ordered items panel:
<div class="wrap-iten-in-cart">
<h3 class="box-title">Products Name</h3>
<ul class="products-cart">
@foreach ($order->orderItems as $item)
<li class="pr-cart-item">
<div class="product-image">
<figure><img src="{{ asset('assets/images/products') }}/{{$item->product->image}}" alt="{{$item->product->name}}"></figure>
</div>
<div class="product-name">
<a class="link-to-product" href="{{route('product.details',['slug'=>$item->product->slug])}}">{{$item->product->name}}</a>
</div>
<div class="price-field produtc-price"><p class="price">${{$item->price}}</p></div>
<div class="quantity">
<h5>{{$item->quantity}}</h5>
</div>
<div class="price-field sub-total"><p class="price">${{$item->price * $item->quantity}}</p></div>
@if($order->status == 'delivered' && $item->rstatus == false)
<div class="price-field sub-total"><p class="price"><a href="{{route('user.review',['order_item_id'=>$item->id])}}">Write Review</a></p></div>
@endif
</li>
@endforeach
</ul>
</div>
Create a new Livewire component:
Switch to the command prompt and run the following command:
php artisan make:livewire user/UserReviewComponent
Run the application again:
php artisan serve
Switch to the project and create a route for this new component.
Go to the web.php
file and inside the user middleware route group, create a new route:
Route::get('/user/review/{order_item_id}',UserReviewComponent::class)->name('user.review');
Open the UserReviewComponent.php
class file and write the following code:
<?php
namespace App\Http\Livewire\User;
use App\Models\OrderItem;
use App\Models\Review;
use Livewire\Component;
class UserReviewComponent extends Component
{
public $order_item_id;
public $rating;
public $comment;
public function mount($order_item_id)
{
$this->order_item_id = $order_item_id;
}
public function updated($fields)
{
$this->validateOnly($fields,[
'rating' => 'required',
'comment' => 'required'
]);
}
public function addReview()
{
$this->validate([
'rating' => 'required',
'comment' => 'required'
]);
$review = new Review();
$review->rating = $this->rating;
$review->comment = $this->comment;
$review->order_item_id= $this->order_item_id;
$review->save();
$orderItem = OrderItem::find($this->order_item_id);
$orderItem->rstatus = true;
$orderItem->save();
session()->flash('message','Your review has been added successfully!');
}
public function render()
{
$orderItem = OrderItem::find($this->order_item_id);
return view('livewire.user.user-review-component',['orderItem'=>$orderItem])->layout('layouts.base');
}
}
Open the user-review-component.blade.php
view file and write the following code:
<div>
<div class="container" style="padding: 30px 0;">
<div class="row">
<div class="col-md-12">
<div id="review_form_wrapper">
<div id="comments">
<h2 class="woocommerce-Reviews-title">Add review for</h2>
<ol class="commentlist">
<li class="comment byuser comment-author-admin bypostauthor even thread-even depth-1" id="li-comment-20">
<div id="comment-20" class="comment_container">
<img alt="" src="{{ asset('assets/images/products') }}/{{$orderItem->product->image}}" height="80" width="80">
<div class="comment-text">
<p class="meta">
<strong class="woocommerce-review__author">{{$orderItem->product->name}}</strong>
</p>
</div>
</div>
</li>
</ol>
</div><!-- #comments -->
<div id="review_form">
@if(Session::has('message'))
<p class="alert alert-success" role="alert">{{Session::get('message')}}</p>
@endif
<div id="respond" class="comment-respond">
<form wire:submit.prevent="addReview" id="commentform" class="comment-form">
<div class="comment-form-rating">
<span>Your rating</span>
<p class="stars">
<label for="rated-1"></label>
<input type="radio" id="rated-1" name="rating" value="1" wire:model="rating">
<label for="rated-2"></label>
<input type="radio" id="rated-2" name="rating" value="2" wire:model="rating">
<label for="rated-3"></label>
<input type="radio" id="rated-3" name="rating" value="3" wire:model="rating">
<label for="rated-4"></label>
<input type="radio" id="rated-4" name="rating" value="4" wire:model="rating">
<label for="rated-5"></label>
<input type="radio" id="rated-5" name="rating" value="5" checked="checked" wire:model="rating">
@error('rating') <span class="text-danger">{{$message}}</span> @enderror
</p>
</div>
<p class="comment-form-comment">
<label for="comment">Your review <span class="required">*</span>
</label>
<textarea id="comment" name="comment" cols="45" rows="8" wire:model="comment"></textarea>
@error('comment') <span class="text-danger">{{$message}}</span> @enderror
</p>
<p class="form-submit">
<input name="submit" type="submit" id="submit" class="submit" value="Submit">
</p>
</form>
</div><!-- .comment-respond-->
</div><!-- #review_form -->
</div><!-- #review_form_wrapper -->
</div>
</div>
</div>
</div>
Now, let's test it out.
Switch to your browser and refresh the page.
Click on the "Details" link, and you'll see that the "Write Review" link is not visible because the order has been canceled.
Let's check another order.
Click on the order that has a status of "Delivered".
You should see the "Write Review" link.
From here, you can set the rating by clicking on the star icon.
In the textarea, you can add a review or comment.
Write a review and click "Submit".
The review has been added, and the "Write Review" link is removed.
In the same way, you can write reviews for other products.
And that's how you can create a user review and rating system on products.