Hi Everyone,
In this post, you will learn how to perform CRUD operations in Laravel 11. We’ll guide you through building a CRUD application from scratch. This blog post is perfect for beginners looking to understand the basics of CRUD operations in Laravel 11.
In this example, we’ll create a product CRUD application using Laravel 11. We’ll start by creating a products table with Laravel migration, followed by setting up routes, controllers, views, and models for the product module. To design the user interface, we’ll use Bootstrap 5.
So, let’s get started with creating a CRUD operation in Laravel 11.
Step 1: Install Laravel 11
First, we’ll install the Laravel 11 application. If you already have a project set up, you can skip this step.
composer create-project laravel/laravel example-app
Step 2: Database Configuration
Open the .env
file and update the database connection details as shown below:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_crud_db
DB_USERNAME=root
DB_PASSWORD=
Step 3: Create Migration
Create a categories
table in your MySQL database using the Laravel Artisan command as follows:
php artisan make:migration create_categories_table --create=categories
After running this command, a migration file will be generated at database/migrations/2024_00_00_000000_create_categories_table.php
. You need to add the following code to this migration file to define the structure of the categories
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('categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('description');
$table->boolean('status')->default(1)->comment('1=visible,0=hidden');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('categories');
}
};
Now, let’s migrate our database using the following command:
php artisan migrate
Step 4: Create a Model Using the Following Command:
php artisan make:model Category
After running this command, you will find the Category.php
file in the app/Models
directory. Open this file and insert the following code:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
use HasFactory;
protected $table = 'categories';
protected $fillable = [
'name',
'description',
'status'
];
}
Step 5: To create a new controller named CategoryController
, run the following command:
php artisan make:controller CategoryController --resource
After the controller is created, navigate to the CategoryController.php
file located at app/Http/Controllers/CategoryController.php
and replace its contents with the code provided below:
<?php
namespace App\Http\Controllers;
use App\Models\Category;
use Illuminate\Http\Request;
class CategoryController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
$categories = Category::paginate(10);
return view('category.index', [
'categories' => $categories
]);
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
return view('category.create');
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'description' => 'required|string|max:255',
'status' => 'nullable',
]);
Category::create([
'name' => $request->name,
'description' => $request->description,
'status' => $request->status == true ? 1:0,
]);
return redirect('/category')->with('status','Category Created Successfully');
}
/**
* Display the specified resource.
*/
public function show(Category $category)
{
return view('category.show', compact('category'));
}
/**
* Show the form for editing the specified resource.
*/
public function edit(Category $category)
{
return view('category.edit', compact('category'));
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, Category $category)
{
$request->validate([
'name' => 'required|string|max:255',
'description' => 'required|string|max:255',
'status' => 'nullable',
]);
$category->update([
'name' => $request->name,
'description' => $request->description,
'status' => $request->status == true ? 1:0,
]);
return redirect('/category')->with('status','Category Updated Successfully');
}
/**
* Remove the specified resource from storage.
*/
public function destroy(Category $category)
{
$category->delete();
return redirect('/category')->with('status','Category Deleted Successfully');
}
}
Step 6: Add Resource Route
Open the routes/web.php
file and add the following route to handle resourceful actions for the CategoryController
:
<?php
use App\Http\Controllers\ProfileController;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\CategoryController;
Route::get('/', function () {
return view('welcome');
});
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware(['auth', 'verified'])->name('dashboard');
Route::middleware('auth')->group(function () {
Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
Route::resource('/category', CategoryController::class);
});
require __DIR__.'/auth.php';
Step 7: Create Blade View Files
Navigate to the resources/views/
directory. Inside this directory, create a folder named category
. Within the category
folder, create the following Blade view files:
index.blade.php
create.blade.php
edit.blade.php
show.blade.php
layout.blade.php
Here’s how to create these files and add the necessary code:
resources/views/category/layout.blade.php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Laravel 11 CRUD Application</title>
<!-- Fonts -->
<link rel="dns-prefetch" href="//fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
<!-- Styles -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
</head>
<body>
<div class="container">
@yield('content')
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe" crossorigin="anonymous"></script>
</body>
</html>
resources/views/category/index.blade.php
@extends('category.layout')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-12">
@session('status')
<div class="alert alert-success">
{{ session('status') }}
</div>
@endsession
<div class="card">
<div class="card-header">
<h4>Categories List
<a href="{{ url('category/create') }}" class="btn btn-primary float-end">Add Category</a>
</h4>
</div>
<div class="card-body">
<table class="table table-stiped table-bordered">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Description</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
@foreach ($categories as $category)
<tr>
<td>{{ $category->id }}</td>
<td>{{ $category->name }}</td>
<td>{{ $category->description }}</td>
<td>{{ $category->status == 1 ? 'Visible':'Hidden' }}</td>
<td>
<a href="{{ route('category.edit', $category->id) }}" class="btn btn-success">Edit</a>
<a href="{{ route('category.show', $category->id) }}" class="btn btn-info">Show</a>
<form action="{{ route('category.destroy', $category->id) }}" method="POST" class="d-inline">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
{{ $categories->links() }}
resources/views/category/create.blade.php
@extends('category.layout')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h4>Create Category
<a href="{{ url('category') }}" class="btn btn-danger float-end">Back</a>
</h4>
</div>
<div class="card-body">
<form action="{{ route('category.store') }}" method="POST">
@csrf
<div class="mb-3">
<label>Name</label>
<input type="text" name="name" class="form-control" />
@error('name') <span class="text-danger">{{ $message }}</span> @enderror
</div>
<div class="mb-3">
<label>Description</label>
<textarea name="description" rows="3" class="form-control"></textarea>
@error('description') <span class="text-danger">{{ $message }}</span> @enderror
</div>
<div class="mb-3">
<label>Status</label>
<br/>
<input type="checkbox" name="status" checked style="width:30px;height:30px;" /> Checked=visible, unchecked=hidden
@error('status') <span class="text-danger">{{ $message }}</span> @enderror
</div>
<div class="mb-3">
<button type="submit" class="btn btn-primary">Save</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
resources/views/category/edit.blade.php
@extends('category.layout')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h4>Edit Category
<a href="{{ url('category') }}" class="btn btn-danger float-end">Back</a>
</h4>
</div>
<div class="card-body">
<form action="{{ route('category.update', $category->id) }}" method="POST">
@csrf
@method('PUT')
<div class="mb-3">
<label>Name</label>
<input type="text" name="name" class="form-control" value="{{ $category->name }}" />
@error('name') <span class="text-danger">{{ $message }}</span> @enderror
</div>
<div class="mb-3">
<label>Description</label>
<textarea name="description" rows="3" class="form-control">{!! $category->description !!}</textarea>
@error('description') <span class="text-danger">{{ $message }}</span> @enderror
</div>
<div class="mb-3">
<label>Status</label>
<br/>
<input type="checkbox" name="status" {{ $category->status == 1 ? 'checked':'' }} style="width:30px;height:30px;" /> Checked=visible, unchecked=hidden
@error('status') <span class="text-danger">{{ $message }}</span> @enderror
</div>
<div class="mb-3">
<button type="submit" class="btn btn-primary">Update</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
resources/views/category/show.blade.php
@extends('category.layout')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h4>Show Category Detail
<a href="{{ url('category') }}" class="btn btn-danger float-end">Back</a>
</h4>
</div>
<div class="card-body">
<div class="mb-3">
<label>Name</label>
<p>
{{ $category->name }}
</p>
</div>
<div class="mb-3">
<label>Description</label>
<p>
{!! $category->description !!}
</p>
</div>
<div class="mb-3">
<label>Status</label>
<br/>
<p>
{{ $category->status == 1 ? 'checked':'' }}
</p>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
Step 8: Add the Pagination class to app/Providers/AppServiceProvider.php
. If it is already included, you can skip this step.
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
//
}
}
Step 9: Serve the application by running the following command:
php artisan serve
Open your web browser, enter the provided URL, and check the app’s output:
http://127.0.0.1:8000/category
That’s the complete information. I trust this will be helpful to you.