Review App Using Laravel 11 & Vue js 3 Composition API Part 2
In the second part of this tutorial, we will create the product and review controllers, and later we will add the functions, and finally, we will add the API routes.
Add product review relationship
First, inside the 'Product Model' let's add the reviews relationship so each product will have one or many reviews.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
use HasFactory;
public function reviews()
{
return $this->hasMany(Review::class)->with('user')->latest();
}
}
Add review user relationship
Next, inside the 'Review Model' let's add the user relationship so each review belongs to a user.
also, we format the created at date to a human-readable date.
<?php
namespace App\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Review extends Model
{
use HasFactory;
protected $fillable = [
'title', 'body', 'rating',
'user_id', 'product_id'
];
public function user()
{
return $this->belongsTo(User::class);
}
public function getCreatedAtAttribute($value)
{
return Carbon::parse($value)->diffForHumans();
}
}
Create the product controller and resource
Next, create a new controller 'ProductController' and a new resource 'ProductResource' and add the code below in the product controller:
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Resources\ProductResource;
use App\Models\Product;
use Illuminate\Http\Request;
class ProductController extends Controller
{
//
public function index()
{
return ProductResource::collection(Product::with('reviews')->latest()->get());
}
public function show(Product $product)
{
return ProductResource::make($product->load('reviews'));
}
}
Create the review controller
Next, create a new controller 'ReviewController' and add the code below in the review controller:
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Resources\ProductResource;
use App\Models\Product;
use App\Models\Review;
use Illuminate\Http\Request;
class ReviewController extends Controller
{
/**
* Store a new review
*/
public function store(Request $request, Product $product)
{
$product->reviews()->create([
'title' => $request->title,
'body' => $request->body,
'rating' => $request->rating,
'user_id' => $request->user_id,
]);
return ProductResource::make($product->load('reviews'));
}
/**
* Update an existing review
*/
public function update(Request $request, Product $product, Review $review)
{
$product->reviews()->find($review->id)->update([
'title' => $request->title,
'body' => $request->body,
'rating' => $request->rating,
'user_id' => $request->user_id,
]);
return ProductResource::make($product->load('reviews'));
}
/**
* delete an existing review
*/
public function delete(Request $request, Product $product)
{
$review = Review::find($request->review_id);
$review->delete();
return ProductResource::make($product->load('reviews'));
}
}
Adding the routes
Next, to add the API routes to Laravel 11 run the command:
php artisan install:api
once done inside the file 'api.php' add the code below:
<?php
use App\Http\Controllers\Api\ProductController;
use App\Http\Controllers\Api\ReviewController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
// Route::get('/user', function (Request $request) {
// return $request->user();
// })->middleware('auth:sanctum');
Route::get('products', [ProductController::class, 'index']);
Route::get('product/{product}/show', [ProductController::class, 'show']);
Route::post('review/{product}/store', [ReviewController::class, 'store']);
Route::put('review/{product}/{review}/update', [ReviewController::class, 'update']);
Route::post('review/{product}/delete', [ReviewController::class, 'delete']);