Table of contents

In this post, I will share a simple Laravel CRUD (Create, Read, Update, and Delete) operation a step-by-step guide with examples that can help beginners. When developing a Laravel application you need to know the basics first on how to create, read, update and delete a Laravel CRUD. Don't worry it is a beginner's friendly guide.
Â
Â
Â
Â
Â
If you don't have a login and registration you can follow my previous tutorial about Laravel 8 authentication.
Â
Step 1: Laravel 8 CRUD Installation
To start our CRUD tutorial we need to install our Laravel 9 first and if you don't have a Laravel 8 installed in your local just run the following command below:
composer create-project --prefer-dist laravel/laravel crud
Â
Or clone my previous tutorial that has an authentication already with Laravel.
Â
After you download it and put it in your htdocs folder if you're using xampp. Then run the following command:
composer update
Â
Once done above we need to install the Laravel Collective Package, run the following command below:
composer require laravelcollective/html
Â
Step 2: Database Configuration
If your Laravel project is fresh then you need to update your database credentials. Just open the .env file in your Laravel 8 project.
Â
.env
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=your_database_name_here DB_USERNAME=your_database_username_here DB_PASSWORD=your_database_password_here
Â
Step 3: Migration Setup
Let's create a migration for our Laravel crud operation. If you are using a fresh Laravel project we need to customize the user's table because I added the username field in my authentication. Here are the complete migrations below:
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name')->nullable(); $table->string('email')->unique(); $table->string('username')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('users'); } }
Â
Now let's run the following command below:
php artisan migrate
Â
Step 4: Laravel CRUD Operation Routes
In my example, I will create manually my CRUD routes. Just open the "routes/web.php" file and add the following routes.
Â
Route::group(['namespace' => 'App\Http\Controllers'], function() { /** * User Routes */ Route::group(['prefix' => 'users'], function() { Route::get('/', 'UsersController@index')->name('users.index'); Route::get('/create', 'UsersController@create')->name('users.create'); Route::post('/create', 'UsersController@store')->name('users.store'); Route::get('/{user}/show', 'UsersController@show')->name('users.show'); Route::get('/{user}/edit', 'UsersController@edit')->name('users.edit'); Route::patch('/{user}/update', 'UsersController@update')->name('users.update'); Route::delete('/{user}/delete', 'UsersController@destroy')->name('users.destroy'); }); });
Â
Step 5: Create Controllers for our Laravel CRUD Example
Now let's create our UserController just run the following command below:
Â
php artisan make:controller UsersController
Â
After running the command above you will find the generated controller to your "App/Http/Controllers". Now let's add our methods for our Laravel crud operation example. Take note that we are using users to do this with a simple example.
Â
In your UsersController
you will have these methods:
Â
1. index()
2. create()
3. store()
4. show()
5. edit()
6. update()
7. destroy()
Â
7 methods that will complete our create, read, update and delete operation in Laravel 8.
Â
Here is the complete code of our UsersController
below:
Â
<?php namespace App\Http\Controllers; use App\Models\User; use Illuminate\Http\Request; use App\Http\Requests\StoreUserRequest; use App\Http\Requests\UpdateUserRequest; class UsersController extends Controller { /** * Display all users * * @return \Illuminate\Http\Response */ public function index() { $users = User::latest()->paginate(10); return view('users.index', compact('users')); } /** * Show form for creating user * * @return \Illuminate\Http\Response */ public function create() { return view('users.create'); } /** * Store a newly created user * * @param User $user * @param StoreUserRequest $request * * @return \Illuminate\Http\Response */ public function store(User $user, StoreUserRequest $request) { //For demo purposes only. When creating user or inviting a user // you should create a generated random password and email it to the user $user->create(array_merge($request->validated(), [ 'password' => 'test' ])); return redirect()->route('users.index') ->withSuccess(__('User created successfully.')); } /** * Show user data * * @param User $user * * @return \Illuminate\Http\Response */ public function show(User $user) { return view('users.show', [ 'user' => $user ]); } /** * Edit user data * * @param User $user * * @return \Illuminate\Http\Response */ public function edit(User $user) { return view('users.edit', [ 'user' => $user ]); } /** * Update user data * * @param User $user * @param UpdateUserRequest $request * * @return \Illuminate\Http\Response */ public function update(User $user, UpdateUserRequest $request) { $user->update($request->validated()); return redirect()->route('users.index') ->withSuccess(__('User updated successfully.')); } /** * Delete user data * * @param User $user * * @return \Illuminate\Http\Response */ public function destroy(User $user) { $user->delete(); return redirect()->route('users.index') ->withSuccess(__('User deleted successfully.')); } }
Â
6. Setup User Model
Kindly see below my User model.
<?php namespace App\Models; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Laravel\Sanctum\HasApiTokens; class User extends Authenticatable { use HasApiTokens, HasFactory, Notifiable; /** * The database table used by the model. * * @var string */ protected $table = 'users'; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'name', 'email', 'username', 'password', ]; /** * The attributes that should be hidden for arrays. * * @var array */ protected $hidden = [ 'password', 'remember_token', ]; /** * The attributes that should be cast to native types. * * @var array */ protected $casts = [ 'email_verified_at' => 'datetime', ]; /** * Always encrypt password when it is updated. * * @param $value * @return string */ public function setPasswordAttribute($value) { $this->attributes['password'] = bcrypt($value); } }
Â
Step 7: Add Blade Files for Our Laravel CRUD
In this last step, we will add our layouts and blades in order to display our Laravel CRUD examples.
Â
In this example in my views I have these files:
Â
layouts/app-master.blade.php
layouts/partials/navbar.blade.php
layouts/partials/messages.blade.php
Â
users/create.blade.php
users/edit.blade.php
users/index.blade.php
users/show.blade.php
Â
See below of our codes of the above views:
Â
resources/views/layouts/app-master.blade.php
Â
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors"> <meta name="generator" content="Hugo 0.87.0"> <title>Fixed top navbar example · Bootstrap v5.1</title> <!-- Bootstrap core CSS --> <link href="{!! url('assets/bootstrap/css/bootstrap.min.css') !!}" rel="stylesheet"> <style> .bd-placeholder-img { font-size: 1.125rem; text-anchor: middle; -webkit-user-select: none; -moz-user-select: none; user-select: none; } @media (min-width: 768px) { .bd-placeholder-img-lg { font-size: 3.5rem; } } .float-right { float: right; } </style> <!-- Custom styles for this template --> <link href="{!! url('assets/css/app.css') !!}" rel="stylesheet"> </head> <body> @include('layouts.partials.navbar') <main class="container mt-5"> @yield('content') </main> <script src="{!! url('assets/bootstrap/js/bootstrap.bundle.min.js') !!}"></script> </body> </html>
Â
resources/views/layouts/partials/navbar.blade.php
<header class="p-3 bg-dark text-white"> <div class="container"> <div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start"> <a href="/" class="d-flex align-items-center mb-2 mb-lg-0 text-white text-decoration-none"> <svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap"><use xlink:href="#bootstrap"/></svg> </a> <ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0"> <li><a href="{{ route('home.index') }}" class="nav-link px-2 text-white">Home</a></li> @auth <li><a href="{{ route('users.index') }}" class="nav-link px-2 text-white">Users</a></li> @endauth </ul> <form class="col-12 col-lg-auto mb-3 mb-lg-0 me-lg-3"> <input type="search" class="form-control form-control-dark" placeholder="Search..." aria-label="Search"> </form> @auth {{auth()->user()->name}} <div class="text-end"> <a href="{{ route('logout.perform') }}" class="btn btn-outline-light me-2">Logout</a> </div> @endauth @guest <div class="text-end"> <a href="{{ route('login.perform') }}" class="btn btn-outline-light me-2">Login</a> <a href="{{ route('register.perform') }}" class="btn btn-warning">Sign-up</a> </div> @endguest </div> </div> </header>
Â
resources/views/layouts/partials/messages.blade.php
@if(Session::get('success', false)) <?php $data = Session::get('success'); ?> @if (is_array($data)) @foreach ($data as $msg) <div class="alert alert-success" role="alert"> <i class="fa fa-check"></i> {{ $msg }} </div> @endforeach @else <div class="alert alert-success" role="alert"> <i class="fa fa-check"></i> {{ $data }} </div> @endif @endif
Â
resources/views/users/index.blade.php
@extends('layouts.app-master') @section('content') <div class="bg-light p-4 rounded"> <h1>Users</h1> <div class="lead"> Manage your users here. <a href="{{ route('users.create') }}" class="btn btn-primary btn-sm float-right">Add new user</a> </div> <div class="mt-2"> @include('layouts.partials.messages') </div> <table class="table table-striped"> <thead> <tr> <th scope="col" width="1%">#</th> <th scope="col" width="15%">Name</th> <th scope="col">Email</th> <th scope="col" width="10%">Username</th> <th scope="col" width="1%" colspan="3"></th> </tr> </thead> <tbody> @foreach($users as $user) <tr> <th scope="row">{{ $user->id }}</th> <td>{{ $user->name }}</td> <td>{{ $user->email }}</td> <td>{{ $user->username }}</td> <td><a href="{{ route('users.show', $user->id) }}" class="btn btn-warning btn-sm">Show</a></td> <td><a href="{{ route('users.edit', $user->id) }}" class="btn btn-info btn-sm">Edit</a></td> <td> {!! Form::open(['method' => 'DELETE','route' => ['users.destroy', $user->id],'style'=>'display:inline']) !!} {!! Form::submit('Delete', ['class' => 'btn btn-danger btn-sm']) !!} {!! Form::close() !!} </td> </tr> @endforeach </tbody> </table> <div class="d-flex"> {!! $users->links() !!} </div> </div> @endsection
Â
resources/views/users/create.blade.php
@extends('layouts.app-master') @section('content') <div class="bg-light p-4 rounded"> <h1>Add new user</h1> <div class="lead"> Add new user and assign role. </div> <div class="container mt-4"> <form method="POST" action=""> @csrf <div class="mb-3"> <label for="name" class="form-label">Name</label> <input value="{{ old('name') }}" type="text" class="form-control" name="name" placeholder="Name" required> @if ($errors->has('name')) <span class="text-danger text-left">{{ $errors->first('name') }}</span> @endif </div> <div class="mb-3"> <label for="email" class="form-label">Email</label> <input value="{{ old('email') }}" type="email" class="form-control" name="email" placeholder="Email address" required> @if ($errors->has('email')) <span class="text-danger text-left">{{ $errors->first('email') }}</span> @endif </div> <div class="mb-3"> <label for="username" class="form-label">Username</label> <input value="{{ old('username') }}" type="text" class="form-control" name="username" placeholder="Username" required> @if ($errors->has('username')) <span class="text-danger text-left">{{ $errors->first('username') }}</span> @endif </div> <button type="submit" class="btn btn-primary">Save user</button> <a href="{{ route('users.index') }}" class="btn btn-default">Back</a> </form> </div> </div> @endsection
Â
resources/views/users/show.blade.php
@extends('layouts.app-master') @section('content') <div class="bg-light p-4 rounded"> <h1>Show user</h1> <div class="lead"> </div> <div class="container mt-4"> <div> Name: {{ $user->name }} </div> <div> Email: {{ $user->email }} </div> <div> Username: {{ $user->username }} </div> </div> </div> <div class="mt-4"> <a href="{{ route('users.edit', $user->id) }}" class="btn btn-info">Edit</a> <a href="{{ route('users.index') }}" class="btn btn-default">Back</a> </div> @endsection
Â
resources/views/users/edit.blade.php
@extends('layouts.app-master') @section('content') <div class="bg-light p-4 rounded"> <h1>Update user</h1> <div class="lead"> </div> <div class="container mt-4"> <form method="post" action="{{ route('users.update', $user->id) }}"> @method('patch') @csrf <div class="mb-3"> <label for="name" class="form-label">Name</label> <input value="{{ $user->name }}" type="text" class="form-control" name="name" placeholder="Name" required> @if ($errors->has('name')) <span class="text-danger text-left">{{ $errors->first('name') }}</span> @endif </div> <div class="mb-3"> <label for="email" class="form-label">Email</label> <input value="{{ $user->email }}" type="email" class="form-control" name="email" placeholder="Email address" required> @if ($errors->has('email')) <span class="text-danger text-left">{{ $errors->first('email') }}</span> @endif </div> <div class="mb-3"> <label for="username" class="form-label">Username</label> <input value="{{ $user->username }}" type="text" class="form-control" name="username" placeholder="Username" required> @if ($errors->has('username')) <span class="text-danger text-left">{{ $errors->first('username') }}</span> @endif </div> <button type="submit" class="btn btn-primary">Update user</button> <a href="{{ route('users.index') }}" class="btn btn-default">Cancel</button> </form> </div> </div> @endsection
Â
Additional:
In your App\Providers\AppServiceProvider class, you need to add the code below inside the boot() function to support the bootstrap paginator.
Paginator::useBootstrap();
Â
Complete code:
<?php namespace App\Providers; use Illuminate\Pagination\Paginator; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { /** * Register any application services. * * @return void */ public function register() { // } /** * Bootstrap any application services. * * @return void */ public function boot() { Paginator::useBootstrap(); } }
Â
Â
Now you have your crud (create, read, update, delete) operations in Laravel 8. You can test it and run the following command:
php artisan serve
Â
Then to your browser navigate this URL:
http://localhost:8000/users
Â
I hope it helps. Thank you for reading. Don't forget to share with your friends if you think this is helpful. Download the source code below to run and test it.
Â
Â
Â
Â
Happy coding :)
Read next