How To Use Soft Delete In Laravel?

0
1027
How To Use Soft Delete In Laravel

In this tutorial, You are going to learn about soft delete in laravel. By using soft delete, instead of removing data from the database, laravel uses a deleted_at column which is a timestamp and nullable by default.

You need a deleted_at column, which can be easily done by adding $table->softDeletes(); into migration schema. After adding column you need to use SoftDeletes trait into the model.

Laravel shipped with default users table migration. First of all, modify the users table schema as below. I removed unnecessary fields and added softDeletes column into it.

/* database > migrations > *_create_users_table.php */

public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('name');
        $table->string('email')->unique();
        $table->softDeletes();
        $table->timestamps();
    });
}

Next, replace the User model with the following code. I kept the User model as simple as possible.

/* app > User.php */

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class User extends Model
{
    use SoftDeletes;

    protected $fillable = [
        'name', 'email'
    ];
}

Finally, migrate database with following command.

php artisan migrate

That’s it! This is a fully functional setup for soft delete for the User model. An example will give you a clear idea. Let’s use users table as an example.

# Seeding Users Table (Optional)

Create UsersTableSeeder with the following command, and update following code into it.

php artisan make:seeder UsersTableSeeder
/* database > seeds > UsersTableSeeder.php */

<?php

use App\User;
use Illuminate\Database\Seeder;
use Faker\Factory as Faker;

class UsersTableSeeder extends Seeder
{
    public function run()
    {
        $faker = Faker::create();

        foreach(range(1,10) as $index)
        {
            User::create([
                'name' => $faker->userName,
                'email' => $faker->safeEmail
            ]);
        }
    }
}

In above function, I’m using faker for generating dummy data. Logic is simple, using range function you can loop through given number.

Next, we need to tell laravel which table needs seeding. For that, open DatabaseSeeder.php and replace the below code.

/* database > seeds > DatabaseSeeder.php */

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    public function run()
    {
        $this->call(UsersTableSeeder::class);
    }
}

Migrate and seed users table with following command to generate users.

php artisan migrate:refresh --seed

# Displaying Users

Let’s create UsersController with following command, and replace below code.

php artisan make:controller UsersController
/* app > Http > Controllers > UsersController.php */

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\User;

class UsersController extends Controller
{
    public function index()
    {
        $users = User::all();
        $trashedUsers = User::onlyTrashed()->get();
        return view('users', compact('users', 'trashedUsers'));
    }

    public function delete(Request $request)
    {
        User::destroy($request->user_id);
        return redirect()->back()->with("msg", "User removed successfully.");
    }

    public function restore(Request $request)
    {
        User::where('id', $request->user_id)->restore();
        return redirect()->back()->with("msg", "User restored successfully.");
    }
}

In index function, I fetched all users and onlyTrashed users. When retriving all users, trashed users will automatically removed from response.

Next, create routes to handle this functions.

/* routes > web.php */

<?php

Route::get('/', 'UsersController@index')->name('users.index');
Route::delete('user/delete/{user_id}', 'UsersController@delete')->name('user.delete');
Route::get('user/restore/{user_id}', 'UsersController@restore')->name('user.restore');

Finally, create users.blade.php and modify it as below.

/* resources > views > users.blade.php */

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Laravel Soft Delete</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<div class="container my-5 align-center">

    @if(session()->has('msg'))
        <div class="alert alert-info alert-dismissible">
            <button type="button" class="close" data-dismiss="alert">×</button>
            {{ session()->get('msg') }}
        </div>
    @endif

    <div class="row">

        {{-- Users List --}}
        <div class="col-md-6">
            <table class="table table-striped">
                <thead>
                <tr class="bg-primary text-white">
                    <th colspan="3" align="center">Current Users</th>
                </tr>
                <tr>
                    <th>Name</th>
                    <th>Email</th>
                    <th>Action</th>
                </tr>
                </thead>
                <tbody>
                @foreach($users as $user)
                    <tr>
                        <td>{{ $user->name }}</td>
                        <td>{{ $user->email }}</td>
                        <td>
                            <button class="btn btn-danger btn-sm" onclick="event.preventDefault();document.getElementById('user_delete_{{ $user->id }}').submit();">
                                <span class="fa fa-trash"></span></button>
                        </td>

                        <form action="{{ route('user.delete', $user->id) }}" method="POST" id="user_delete_{{ $user->id }}">
                            {{ csrf_field() }}
                            {{ method_field('DELETE') }}
                        </form>
                    </tr>
                @endforeach
                </tbody>
            </table>
        </div>

        {{-- Trashed Users List --}}
        <div class="col-md-6">
            <table class="table table-striped">
                <thead>
                <tr class="bg-primary text-white">
                    <th colspan="3" align="center">Trashed Users</th>
                </tr>
                <tr>
                    <th>Name</th>
                    <th>Email</th>
                    <th>Action</th>
                </tr>
                </thead>
                <tbody>
                @foreach($trashedUsers as $user)
                    <tr>
                        <td>{{ $user->name }}</td>
                        <td>{{ $user->email }}</td>
                        <td><a href="{{ route('user.restore', $user->id) }}" class="btn btn-info btn-sm"><span class="fa fa-refresh"></span> Restore</a></td>
                    </tr>
                @endforeach
                </tbody>
            </table>
        </div>
    </div>
</div>
</body>
</html>

Start php server with following command and open localhost:8000 in browser.

php artisan serve

As you can see, you will have two tables which have current and trashed users. After deleting a user from current users it will be displayed in the trashed users. Similarly, after restoring a user from trashed users it will be displayed in current users.

# Force Delete Users

If you want to force delete users just update delete method in UsersController.

/* app > Http > Controllers > UsersController.php */

....

public function delete(Request $request)
{
    User::where('id', $request->user_id)->forceDelete();
    return redirect()->back()->with("msg", "User removed successfully.");
}
....

Remember, force deleted users are not restorable. Try to delete a user after updating the delete function. You will see users not displaying in the trashed users list.

Learn more about Laravel Framework

Previous articleHow To Use Yajra Datatables Laravel?
Next articleWhat Is Accessors & Mutators In Laravel?
Welcome to the world of web development, where technology and creativity come together to bring ideas to life. My name is Keyur Gadher, and as a web development blogger, I am here to share my knowledge and experience with you. From front-end web development to back-end programming, I will provide you with valuable tips, tricks, and techniques to help you create beautiful and functional websites that are tailored to your specific needs. Whether you're a beginner or a seasoned pro, I am here to help you take your web development skills to the next level. Join me today and let's start coding!

LEAVE A REPLY

Please enter your comment!
Please enter your name here