Build a CRUD (Create, Read, Update, Delete) application including Image using Laravel 12 and MySQL by following these steps:
- Install Laravel 12
Begin by installing Laravel 12 using Composer:
composer create-project --prefer-dist laravel/laravel laravel12imgcrud
- Configure the MySQL Database
Set up your MySQL database and update the .env file in your Laravel project with the appropriate database credentials:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel12imgcrud
DB_USERNAME=root
DB_PASSWORD=admin@123
- Create a Migration
Generate a migration to create a products table:
php artisan make:migration create_products_table --create=products
In the generated migration file, define the table structure:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->text('detail');
$table->string('image');
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('products');
}
};
Run the migration to create the table:
php artisan migrate
- Create the Product Model and Controller
Generate the Product model and its corresponding controller:
php artisan make:model Product
php artisan make:controller ProductController --resource
or
php artisan make:model Product -mcr
add “$fillable” in Model Product.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $fillable = [
'name',
'detail',
'image',
];
}
- Define Routes
In routes/web.php, add resource routes for the ProductController:
use App\Http\Controllers\ProductController;
Route::resource('products', ProductController::class);
- Implement Controller Methods
In ProductController, implement the necessary CRUD methods:
use App\Models\Product;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
class ProductController extends Controller
{
public function index()
{
$products = Product::all();
return view('products.index', compact('products'));
}
public function create()
{
return view('products.create');
}
public function store(Request $request)
{
$request->validate([
'name' => 'required',
'detail' => 'required',
'image' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048',
]);
$imageName = time().'.'.$request->image->extension();
$request->image->move(public_path('images'), $imageName);
Product::create([
'name' => $request->name,
'detail' => $request->detail,
'image' => $imageName,
]);
return redirect()->route('products.index')->with('success', 'Product created successfully.');
}
public function show(Product $product)
{
return view('products.show', compact('product'));
}
public function edit(Product $product)
{
return view('products.edit', compact('product'));
}
public function update(Request $request, Product $product)
{
$request->validate([
'name' => 'required',
'detail' => 'required',
'image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
]);
// Initialize an array to hold updated data
$updateData = [
'name' => $request->name,
'detail' => $request->detail,
];
// Check if a new image is uploaded
if ($request->hasFile('image')) {
// Delete the old image if it exists
$oldImagePath = public_path('images/' . $product->image);
if (File::exists($oldImagePath)) {
File::delete($oldImagePath);
}
// Upload the new image
$imageName = time().'.'.$request->image->extension();
$request->image->move(public_path('images'), $imageName);
// Add the new image name to the update data
$updateData['image'] = $imageName;
}
// Update the product
$product->update($updateData);
return redirect()->route('products.index')->with('success', 'Product updated successfully.');
}
public function destroy(Product $product)
{
// Delete the image file from storage
$imagePath = public_path('images/' . $product->image);
if (File::exists($imagePath)) {
File::delete($imagePath);
}
$product->delete();
return redirect()->route('products.index')->with('success', 'Product deleted successfully.');
}
}
- Create Blade Views
In the resources/views/products directory, create the following Blade templates:
index.blade.php: Displays a list of products.
resources/views/products/index.blade.php
Displays a list of products with options to create, edit, view, and delete.
@extends('layouts.app')
@section('content')
<div class="container">
<h2 class="mb-4">Product List</h2>
@if ($message = Session::get('success'))
<div class="alert alert-success">
{{ $message }}
</div>
@endif
<a href="{{ route('products.create') }}" class="btn btn-primary mb-3">Create Product</a>
<table class="table table-bordered">
<tr>
<th>ID</th>
<th>Name</th>
<th>Details</th>
<th>Image</th>
<th>Actions</th>
</tr>
@foreach ($products as $product)
<tr>
<td>{{ $product->id }}</td>
<td>{{ $product->name }}</td>
<td>{{ $product->detail }}</td>
<td><img src="{{ asset('images/' . $product->image) }}" alt="{{ $product->name }}" height="50" width="50" ></td>
<td>
<a href="{{ route('products.show', $product->id) }}" class="btn btn-info">Show</a>
<a href="{{ route('products.edit', $product->id) }}" class="btn btn-warning">Edit</a>
<form action="{{ route('products.destroy', $product->id) }}" method="POST" style="display:inline;">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger" onclick="return confirm('Are you sure?')">Delete</button>
</form>
</td>
</tr>
@endforeach
</table>
</div>
@endsection
create.blade.php: Form to create a new product.
resources/views/products/create.blade.php
Form to create a new product.
@extends('layouts.app')
@section('content')
<div class="container">
<h2>Create Product</h2>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form action="{{ route('products.store') }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="form-group">
<label for="name">Product Name:</label>
<input type="text" name="name" class="form-control" required>
</div>
<div class="form-group">
<label for="detail">Product Detail:</label>
<textarea name="detail" class="form-control" required></textarea>
</div>
<div class="form-group">
<label for="image">Image:</label>
<input type="file" name="image" required>
</div>
<button type="submit" class="btn btn-success">Submit</button>
<a href="{{ route('products.index') }}" class="btn btn-secondary">Back</a>
</form>
</div>
@endsection
edit.blade.php: Form to edit an existing product.
resources/views/products/edit.blade.php
Form to edit an existing product.
@extends('layouts.app')
@section('content')
<div class="container">
<h2>Edit Product</h2>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form action="{{ route('products.update', $product->id) }}" method="POST" enctype="multipart/form-data">
@csrf
@method('PUT')
<div class="form-group">
<label for="name">Product Name:</label>
<input type="text" name="name" class="form-control" value="{{ $product->name }}" required>
</div>
<div class="form-group">
<label for="detail">Product Detail:</label>
<textarea name="detail" class="form-control" required>{{ $product->detail }}</textarea>
</div>
<div class="form-group">
<label for="image">Image:</label>
<img src="{{ asset('images/' . $product->image) }}" alt="{{ $product->name }}" height="50" width="50" >
<input type="file" name="image" >
</div>
<button type="submit" class="btn btn-success">Update</button>
<a href="{{ route('products.index') }}" class="btn btn-secondary">Back</a>
</form>
</div>
@endsection
show.blade.php: Displays a single product’s details.
resources/views/products/show.blade.php
Displays a single product’s details.
@extends('layouts.app')
@section('content')
<div class="container">
<h2>Product Details</h2>
<div class="card">
<div class="card-body">
<h3>{{ $product->name }}</h3>
<p>{{ $product->detail }}</p>
<p><img src="{{ asset('images/' . $product->image) }}" alt="{{ $product->name }}" height="50" width="50" ></p>
</div>
</div>
<a href="{{ route('products.index') }}" class="btn btn-secondary mt-3">Back</a>
</div>
@endsection
resources/views/layouts/app.blade.php
A simple layout template to wrap around all pages.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Laravel CRUD with Image - chirags.in</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container mt-5">
@yield('content')
</div>
</body>
</html>
- Run the Application
Start the Laravel development server:
php artisan serve
Visit
http://localhost:8000/products
to access the CRUD application.
How to Use
Visit /products to view all products.
Click “Create Product” to add a new product.
Click “Edit” to update a product.
Click “Show” to view details.
Click “Delete” to remove a product.
For any doubts and query, please write on YouTube video comments section.
Note : Flow the Process shown in video.
😉Please, Subscribe and like for more videos:
https://www.youtube.com/@chiragstutorial
💛Don’t forget to, 💘Follow, 💝Like, 💖Share 💙&, Comment
Thanks & Regards,
Chitt Ranjan Mahto “Chirag”
Note: All scripts used in this demo will be available in our website.
Link will be available in description.