CRUD-Operations-with-Laravel-11

CRUD Operations with Laravel 11: Building a Product Management Application

Hello there! In this tutorial, I’ll guide you through a step-by-step example of performing CRUD operations in Laravel 11.

Firstly, let’s understand what CRUD stands for: It’s an acronym derived from the world of programming, representing the four fundamental operations necessary for persistent storage in your application: create, read, update, and delete.

In this tutorial, we’ll be building a product management application using Laravel 11. We’ll start by creating a products table with ‘name’ and ‘detail’ columns using Laravel 11 migration. Then, we’ll set up routes, a controller, views, and model files specifically for the product module. To make our application visually appealing, we’ll utilize Bootstrap 5 for design.

Now, let’s dive into the steps to create CRUD operations with Laravel 11. Follow along to learn and implement these functionalities seamlessly.

Getting Started: Installing Laravel 11 for Your CRUD Application

To begin, let’s start by setting up a new Laravel 11 application from scratch. This ensures that we have a clean slate to work with. You can do this by opening your terminal or command prompt and executing the following command:

composer create-project laravel/laravel example-app

Configuring MySQL Database for Your Laravel 11 Application

Now that we have our Laravel 11 application set up, the next step is to configure MySQL database for it. This involves setting up the necessary database credentials and connections so that Laravel can interact with MySQL. Let’s walk through the process.

In Laravel 11, the default database connection is configured to use SQLite. However, if you prefer to use MySQL instead, you’ll need to add a MySQL connection configuration in the .env file. This includes specifying the database name, username, and password for your MySQL database.

.env file

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=here your database name
DB_USERNAME=here database username
DB_PASSWORD=here database password

Generating Migrations: Defining Your Database Schema

Now that we’ve configured our database connection, the next step is to create migrations. Migrations in Laravel are used to define and manage the structure of your database tables. Let’s proceed with generating migrations for our application.

In this step, we’ll create a migration file to define the structure of our “products” table in the database. This table will have columns for “name” and “details”. Let’s generate the migration file using the following command:

php artisan make:migration create_products_table --create=products

After running the above command, you’ll find a newly created file in the ‘database/migrations’ directory. Open this file and paste the following code to define the structure of the ‘products’ table:

<?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('products', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->text('detail');
            $table->timestamps();
        });
    }
  
    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('products');
    }
};

Now, execute the migration by running the following command:

php artisan migrate

Implementing Form Request Validation

In this step, we’ll focus on ensuring the data submitted through forms in our Laravel 11 application is validated properly. To achieve this, we’ll create a Form Request Validation class. This class will handle validation rules for incoming requests, ensuring that the data meets the specified criteria before further processing.
we’ll create a Form Request Validation class specifically for the store() and update() methods in our controller. This class will define the validation rules for incoming requests and will be utilized within the controller file. Let’s proceed with creating it.

php artisan make:request ProductStoreRequest

Below is the code snippet to be placed within your request class:

app/Http/Requests/ProductStoreRequest.php

<?php
  
namespace App\Http\Requests;
  
use Illuminate\Foundation\Http\FormRequest;
  
class ProductStoreRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return true;
    }
  
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array|string>
     */
    public function rules(): array
    {
        return [
            'name' => 'required',
            'detail' => 'required'
        ];
    }
}

Now, let’s repeat the process for the Update Request Class.

php artisan make:request ProductUpdateRequest

Here’s the code snippet to include in your Update Request Class:

app/Http/Requests/ProductUpdateRequest.php

<?php
   
namespace App\Http\Requests;
  
use Illuminate\Foundation\Http\FormRequest;
  
class ProductUpdateRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array|string>
     */
    public function rules(): array
    {
        return [
            'name' => 'required',
            'detail' => 'required'
        ];
    }
}

Creating Controller and Model for Product Management

In this step, we’ll create both the controller and model files necessary for managing products in our Laravel 11 application. The controller will handle the logic for CRUD operations, while the model will represent the data structure and interact with the database. Let’s proceed with creating these files.

 artisan make:controller ProductController --resource --model=Product

After running the following command, you’ll find a new file located at: ‘app/Http/Controllers/ProductController.php’.

This controller will contain seven default methods:

  1. index()
  2. create()
  3. store()
  4. show()
  5. edit()
  6. update()
  7. destroy()

Let’s copy the provided code and paste it into the ProductController.php file.
app/Http/Controllers/ProductController.php

<?php
    
namespace App\Http\Controllers;
    
use App\Models\Product;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\View\View;
use App\Http\Requests\ProductStoreRequest;
use App\Http\Requests\ProductUpdateRequest;
    
class ProductController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index(): View
    {
        $products = Product::latest()->paginate(5);
          
        return view('products.index', compact('products'))
                    ->with('i', (request()->input('page', 1) - 1) * 5);
    }
    
    /**
     * Show the form for creating a new resource.
     */
    public function create(): View
    {
        return view('products.create');
    }
    
    /**
     * Store a newly created resource in storage.
     */
    public function store(ProductStoreRequest $request): RedirectResponse
    {   
        Product::create($request->validated());
           
        return redirect()->route('products.index')
                         ->with('success', 'Product created successfully.');
    }
  
    /**
     * Display the specified resource.
     */
    public function show(Product $product): View
    {
        return view('products.show',compact('product'));
    }
  
    /**
     * Show the form for editing the specified resource.
     */
    public function edit(Product $product): View
    {
        return view('products.edit',compact('product'));
    }
  
    /**
     * Update the specified resource in storage.
     */
    public function update(ProductUpdateRequest $request, Product $product): RedirectResponse
    {
        $product->update($request->validated());
          
        return redirect()->route('products.index')
                        ->with('success','Product updated successfully');
    }
  
    /**
     * Remove the specified resource from storage.
     */
    public function destroy(Product $product): RedirectResponse
    {
        $product->delete();
           
        return redirect()->route('products.index')
                        ->with('success','Product deleted successfully');
    }
}

Let’s proceed by updating the Product model code as follows:
app/Models/Product.php

<?php
  
namespace App\Models;
  
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
  
class Product extends Model
{
    use HasFactory;
  
    protected $fillable = [
        'name',
        'detail',
    ];
}

Adding Resource Route for Product Management

In this step, we’ll define a resource route for managing products in our Laravel 11 application.
Open your ‘routes/web.php’ file and add the following route:
routes/web.php

<?php
  
use Illuminate\Support\Facades\Route;
  
use App\Http\Controllers\ProductController;
  
Route::get('/', function () {
    return view('welcome');
});
  
Route::resource('products', ProductController::class);

Updating AppServiceProvider for Database Migrations

Here, we’ll import Bootstrap 5 for pagination in our application. To do so, we need to update the AppServiceProvider.php file. Let’s proceed with the update.
app/Provides/AppServiceProvider.php

<?php
  
namespace App\Providers;
  
use Illuminate\Support\ServiceProvider;
use Illuminate\Pagination\Paginator;
  
class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
           
    }
  
    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        Paginator::useBootstrapFive();
    }
}

Adding Blade Files for User Interface

For our final step, we’ll create the necessary Blade files for our CRUD application. Let’s start by creating a layout file named “layout.blade.php”. Then, we’ll create a new folder called “products” to organize our product-related views. Within this folder, we’ll create Blade files for index, create, edit, and show operations. Let’s proceed by creating these files and adding the corresponding code to each.

resources/views/products/layout.blade.php

<!DOCTYPE html>
<html>
<head>
    <title>Laravel 11 CRUD Application -adarshjaiswal.com</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" />
</head>
<body>
      
<div class="container">
    @yield('content')
</div>
      
</body>
</html>

resources/views/products/index.blade.php

@extends('products.layout')
   
@section('content')
  
<div class="card mt-5">
  <h2 class="card-header">Laravel 11 CRUD Example -adarshjaiswal.com</h2>
  <div class="card-body">
          
        @session('success')
            <div class="alert alert-success" role="alert"> {{ $value }} </div>
        @endsession
  
        <div class="d-grid gap-2 d-md-flex justify-content-md-end">
            <a class="btn btn-success btn-sm" href="{{ route('products.create') }}"> <i class="fa fa-plus"></i> Create New Product</a>
        </div>
  
        <table class="table table-bordered table-striped mt-4">
            <thead>
                <tr>
                    <th width="80px">No</th>
                    <th>Name</th>
                    <th>Details</th>
                    <th width="250px">Action</th>
                </tr>
            </thead>
  
            <tbody>
            @forelse ($products as $product)
                <tr>
                    <td>{{ ++$i }}</td>
                    <td>{{ $product->name }}</td>
                    <td>{{ $product->detail }}</td>
                    <td>
                        <form action="{{ route('products.destroy',$product->id) }}" method="POST">
             
                            <a class="btn btn-info btn-sm" href="{{ route('products.show',$product->id) }}"><i class="fa-solid fa-list"></i> Show</a>
              
                            <a class="btn btn-primary btn-sm" href="{{ route('products.edit',$product->id) }}"><i class="fa-solid fa-pen-to-square"></i> Edit</a>
             
                            @csrf
                            @method('DELETE')
                
                            <button type="submit" class="btn btn-danger btn-sm"><i class="fa-solid fa-trash"></i> Delete</button>
                        </form>
                    </td>
                </tr>
            @empty
                <tr>
                    <td colspan="4">There are no data.</td>
                </tr>
            @endforelse
            </tbody>
  
        </table>
        
        {!! $products->links() !!}
  
  </div>
</div>  
@endsection

resources/views/products/create.blade.php

@extends('products.layout')
    
@section('content')
  
<div class="card mt-5">
  <h2 class="card-header">Add New Product</h2>
  <div class="card-body">
  
    <div class="d-grid gap-2 d-md-flex justify-content-md-end">
        <a class="btn btn-primary btn-sm" href="{{ route('products.index') }}"><i class="fa fa-arrow-left"></i> Back</a>
    </div>
  
    <form action="{{ route('products.store') }}" method="POST">
        @csrf
  
        <div class="mb-3">
            <label for="inputName" class="form-label"><strong>Name:</strong></label>
            <input 
                type="text" 
                name="name" 
                class="form-control @error('name') is-invalid @enderror" 
                id="inputName" 
                placeholder="Name">
            @error('name')
                <div class="form-text text-danger">{{ $message }}</div>
            @enderror
        </div>
  
        <div class="mb-3">
            <label for="inputDetail" class="form-label"><strong>Detail:</strong></label>
            <textarea 
                class="form-control @error('detail') is-invalid @enderror" 
                style="height:150px" 
                name="detail" 
                id="inputDetail" 
                placeholder="Detail"></textarea>
            @error('detail')
                <div class="form-text text-danger">{{ $message }}</div>
            @enderror
        </div>
        <button type="submit" class="btn btn-success"><i class="fa-solid fa-floppy-disk"></i> Submit</button>
    </form>
  
  </div>
</div>
@endsection

resources/views/products/edit.blade.php

@extends('products.layout')
    
@section('content')
  
<div class="card mt-5">
  <h2 class="card-header">Edit Product</h2>
  <div class="card-body">
  
    <div class="d-grid gap-2 d-md-flex justify-content-md-end">
        <a class="btn btn-primary btn-sm" href="{{ route('products.index') }}"><i class="fa fa-arrow-left"></i> Back</a>
    </div>
  
    <form action="{{ route('products.update',$product->id) }}" method="POST">
        @csrf
        @method('PUT')
  
        <div class="mb-3">
            <label for="inputName" class="form-label"><strong>Name:</strong></label>
            <input 
                type="text" 
                name="name" 
                value="{{ $product->name }}"
                class="form-control @error('name') is-invalid @enderror" 
                id="inputName" 
                placeholder="Name">
            @error('name')
                <div class="form-text text-danger">{{ $message }}</div>
            @enderror
        </div>
  
        <div class="mb-3">
            <label for="inputDetail" class="form-label"><strong>Detail:</strong></label>
            <textarea 
                class="form-control @error('detail') is-invalid @enderror" 
                style="height:150px" 
                name="detail" 
                id="inputDetail" 
                placeholder="Detail">{{ $product->detail }}</textarea>
            @error('detail')
                <div class="form-text text-danger">{{ $message }}</div>
            @enderror
        </div>
        <button type="submit" class="btn btn-success"><i class="fa-solid fa-floppy-disk"></i> Update</button>
    </form>
  
  </div>
</div>
@endsection

resources/views/products/show.blade.php

@extends('products.layout')
  
@section('content')

<div class="card mt-5">
  <h2 class="card-header">Show Product</h2>
  <div class="card-body">
  
    <div class="d-grid gap-2 d-md-flex justify-content-md-end">
        <a class="btn btn-primary btn-sm" href="{{ route('products.index') }}"><i class="fa fa-arrow-left"></i> Back</a>
    </div>
  
    <div class="row">
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Name:</strong> <br/>
                {{ $product->name }}
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12 mt-2">
            <div class="form-group">
                <strong>Details:</strong> <br/>
                {{ $product->detail }}
            </div>
        </div>
    </div>
  
  </div>
</div>
@endsection

Running Your Laravel Application

To launch your Laravel application, navigate to the project directory in your terminal or command prompt, and then execute the following command:

php artisan serve

Now, Go to your web browser, type the given URL and view the app output:

http://localhost:8000/products

This command starts a development server, and you’ll receive a message indicating the server is running. To access your Laravel application, open your web browser and enter the URL provided in the terminal, typically something like ‘http://127.0.0.1:8000‘. Your application should now be up and running!

Below, you’ll find the layout file:

Details Page layout

Edit Page layout

I sincerely hope that the information provided here proves to be beneficial and assists you in achieving your goals. If you have any questions or need further clarification, please don’t hesitate to reach out on Whatsapp or Email on krishj067@gmail.com

Leave a Comment

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