Laravel 12 CRUD (Create, Read, Update and Delete) Operation including Image with MySQL Database

Laravel 12 CRUD (Create, Read, Update and Delete) Operation including Image with MySQL Database

Build a CRUD (Create, Read, Update, Delete) application including Image using Laravel 12 and MySQL by following these steps:

  1. Install Laravel 12

Begin by installing Laravel 12 using Composer:

composer create-project --prefer-dist laravel/laravel laravel12imgcrud
  1. 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
  1. 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
  1. 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',
    ];
}
  1. Define Routes

In routes/web.php, add resource routes for the ProductController:

use App\Http\Controllers\ProductController;

Route::resource('products', ProductController::class);
  1. 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.');
    }
}
  1. 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>
  1. 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.

Leave a Comment

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.