Here's how you can create a reviews
table to associate customer reviews with your products
table:
-
Create a Migration: Use Artisan to create a new migration for the
reviews
table:php artisan make:migration create_reviews_table
-
Define the Schema: Open the generated migration file in
database/migrations
and define thereviews
table structure:<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. */ public function up(): void { Schema::create('reviews', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('product_id'); // Foreign key to products table $table->unsignedBigInteger('user_id')->nullable(); // Optional user ID for logged-in reviewers $table->string('reviewer_name')->nullable(); // For non-logged-in users $table->text('review'); // The actual review text $table->tinyInteger('rating')->unsigned()->default(0); // Rating (1-5) $table->boolean('is_approved')->default(false); // Admin approval for the review $table->timestamps(); // Foreign key constraints $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade'); $table->foreign('user_id')->references('id')->on('users')->onDelete('set null'); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('reviews'); } };
-
Run the Migration: Apply the migration using:
php artisan migrate
product_id
: Links the review to a specific product.user_id
: Links the review to a user if the reviewer is logged in.reviewer_name
: Optional field for guests who submit reviews.review
: The text content of the review.rating
: A numeric value for rating (e.g., 1–5 stars).is_approved
: Ensures that reviews are moderated before being displayed.
-
Product Model: Add a relationship to the
Review
model:public function reviews() { return $this->hasMany(Review::class); }
-
Review Model: Define the relationship to the
Product
model:public function product() { return $this->belongsTo(Product::class); }
You can add dummy data to the reviews
table in a seeder:
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class ReviewSeeder extends Seeder
{
public function run()
{
$products = DB::table('products')->pluck('id');
foreach ($products as $productId) {
DB::table('reviews')->insert([
'product_id' => $productId,
'reviewer_name' => 'John Doe',
'review' => 'This is a sample review for product ' . $productId,
'rating' => rand(1, 5),
'is_approved' => true,
'created_at' => now(),
'updated_at' => now(),
]);
}
}
}
You can show reviews for a product like this:
@foreach($product->reviews as $review)
<div>
<strong>{{ $review->reviewer_name }}</strong>
<p>{{ $review->review }}</p>
<span>Rating: {{ $review->rating }}/5</span>
</div>
@endforeach