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