How to create Recycle Bin with Soft Delete in Laravel 8 and 7
Tags: php, laravel, webdev
Published: 2020-11-06 23:01:05

Hello guys, I want to treat some Laravel concepts about deleting, sometimes we may want to design our application so that even though the user deletes a data, it is not permanently deleted, it will still remain in the database but will not show up in the view. Laravel has provided this functionality out of the box for us called **softDelete**, so I am going to illustrate how to delete data and view the deleted data and also how to restore the deleted data, and finally, how to permanently delete the data, I called this concept **Recycle Bin**.
We are going to be using the code from my previous article [Laravel 8 CRUD App, A simple guide](https://dev.to/kingsconsult/laravel-8-crud-bi9), the [repo](https://github.com/Kingsconsult/laravel_8_crud)

If you prefer videos, you can watch the video from [Youtube](https://www.youtube.com/watch?v=-ujO2t9mHPU)

Click on my [profile](https://dev.to/kingsconsult) to follow me to get more updates.

### **Step 1: Setup the app**
1. git clone https://github.com/Kingsconsult/laravel_8_crud.git
2. cd laravel_8_crud/
3. composer install
4. npm install
5. cp .env.example .env
6. php artisan key:generate
7. Add your database config in the .env file (you can check my articles on how to achieve that)
8. php artisan migrate
9. php artisan serve (if the server opens up, http://127.0.0.1:8000,  then we are good to go)
![localhost](https://res.cloudinary.com/kingsconsult/image/upload/v1600705305/laravel%208%20modal/4_pp7r76.png)
10. Navigate to http://127.0.0.1:8000/projects

### **Step 2: Add delete_at column to projects table**
In Laravel Soft Delete, data are not actually deleted from the database but a **deleted_at** attribute is added to the data, so when we are querying data from the database, Eloquent looks for data with null **deleted_at** value and give out, but when a data has non-null **deleted_at** value, it treats it as a deleted data.
So we need to add it and run our migration again.
![create migration file](https://res.cloudinary.com/kingsconsult/image/upload/v1604689251/laravel%208%20recycle%20bin/1_ybdh1n.png)
### **Step 3: Add the delete_at column to the migration file**
Running the command in step 2 will create a migration file in **database/migrations/**, edit the file and add **$table->softDeletes();** to the **up()** function and also **$table->dropSoftDeletes();** to the **down()** function, our migration file looks like this
![migration file](https://res.cloudinary.com/kingsconsult/image/upload/v1604689251/laravel%208%20recycle%20bin/4_oznfem.png)
### **Step 4: Run migration again**
We need to run the migration again so that the new column will be added to the existing table
> php artisan migrate

![migration](https://res.cloudinary.com/kingsconsult/image/upload/v1604689251/laravel%208%20recycle%20bin/2_tb8u0a.png)
Going to our database, you will see the new column created with values Null 
![database](https://res.cloudinary.com/kingsconsult/image/upload/v1604689686/laravel%208%20recycle%20bin/3_wc23th.png)
### **Step 5: Enable the softdelete trait on the model**
Go to **app/Models/Project.php** and add the soft delete trait, this trait will tell the model to only add a date to the model that is deleted, but not deleting it permanently.
>  use SoftDeletes;

 Also, add the path of the trait at the top
> use Illuminate\Database\Eloquent\SoftDeletes;

### **Step 6: Create the routes to get all deleted projects**
Go to **routes/web.php** and add the route to get all deleted projects 
> Route::get('projects/deletedprojects', [ProjectController::class, 'getDeleteProjects'])->name('getDeleteProjects');

### **Step 7: Create the Controller Method**
In our route above, we specified a **getDeletedProjects** methods in the ProjectController class, so we create that method. Go to **app/Http/Controllers/ProjectController.php** and add this method
```
    public function getDeleteProjects() {
        $projects = Project::onlyTrashed()->paginate(10);

        return view('projects.deletedprojects', compact('projects'))
            ->with('i', (request()->input('page', 1) - 1) * 10);
    }
```
From the method above, we used an eloquent function **onlyTrashed()**, this function only fetches the model with non-null deleted_at values, so it will fetch just the projects that are deleted. 
### **Step 8: Create the blade file to view all deleted project**
From our **getDeletedProjects()** method above, we return to **deletedprojects** view, so we need to create that, go to **resources/views/projects/** and create the file **deletedprojects.blade.php** and copy the index page and edit to this
```
@extends('layouts.app')

@section('content')
    <div class="row">
        <div class="col-lg-12 margin-tb">
            <div class="pull-left">
                <h2>Laravel 8 CRUD </h2>
            </div>
        </div>
    </div>

    <div class="pull-left ">
        <a class="btn btn-success" href="{{ route('projects.index') }}" title="Back to Index"> <i class="fas fa-home"></i> </a>
    </div>
    <div class="">
        <div class="mx-auto pull-right">
            <div class="">
                <form action="{{ route('projects.index') }}" method="GET" role="search">

                    <div class="input-group">
                        <span class="input-group-btn mr-5 mt-1">
                            <button class="btn btn-info" type="submit" title="Search projects">
                                <span class="fas fa-search"></span>
                            </button>
                        </span>
                        <input type="text" class="form-control mr-2" name="term" placeholder="Search projects" id="term">
                        <a href="{{ route('projects.index') }}" class=" mt-1">
                            <span class="input-group-btn">
                                <button class="btn btn-danger" type="button" title="Refresh page">
                                    <span class="fas fa-sync-alt"></span>
                                </button>
                            </span>
                        </a>
                    </div>
                </form>
            </div>
        </div>
    </div>

    @if ($message = Session::get('success'))
        <div class="alert alert-success">
            <p>{{ $message }}</p>
        </div>
    @endif

    <table class="table table-bordered table-responsive-lg">
        <tr>
            <th>No</th>
            <th>Name</th>
            <th>Introduction</th>
            <th>Location</th>
            <th>Cost</th>
            <th>Date Deleted</th>
            <th>Action</th>
        </tr>
        @foreach ($projects as $project)
            <tr>
                <td>{{ ++$i }}</td>
                <td>{{ $project->name }}</td>
                <td>{{ $project->introduction }}</td>
                <td>{{ $project->location }}</td>
                <td>{{ $project->cost }}</td>
                <td>{{ date_format($project->deleted_at, 'jS M Y') }}</td>
                <td>
                    <a href="{{ route('restoreDeletedProjects', $project->id) }}" title="restore project">
                        <i class="fas fa-window-restore text-success  fa-lg"></i>
                    </a>
                    <a href="{{ route('deletePermanently', $project->id) }}" title="Permanently delete">
                        <i class="fas fa-trash text-danger  fa-lg"></i>
                    </a>
                </td>
            </tr>
        @endforeach
    </table>

    {!! $projects->links() !!}


@endsection
```
In the action column of a project from the code above, we added an icon to restore a deleted file, this will remove the value in the deleted_at in the table and we also added another icon to delete a project permanently, this will permanently delete the project from the database.
Next, we need to create a function to restore the deleted project.
### **Step 9: Create Route to Restore Deleted Project**
> Route::get('projects/deletedprojects/{id}', [ProjectController::class, 'restoreDeletedProjects'])->name('restoreDeletedProjects');

In our route, we also specify a controller method **restoreDeletedProjects**, so we head to ProjectController and create the method
### **Step 10: Create Controller Method to Restore Deleted Project**
Go to **app/Http/Controllers/ProjectController.php** and add this method
```
    public function restoreDeletedProjects($id) 
    {
        
        $project = Project::where('id', $id)->withTrashed()->first();

        $project->restore();

        return redirect()->route('projects.index')
            ->with('success', 'You successfully restored the project');
    }
```
### **Step 11: Create Route to permanently delete Project**
We need to also create a functionality, to permanently delete a project that we don't want to leave in the database, so let's create the route
> Route::get('projects/retoreprojects/{id}', [ProjectController::class, 'deletePermanently'])->name('deletePermanently');

### **Step 12: Create the Controller Method**
```
    public function deletePermanently($id)
    {
        $project = Project::where('id', $id)->withTrashed()->first();

        $project->forceDelete();

        return redirect()->route('projects.index')
            ->with('success', 'You successfully deleted the project fromt the Recycle Bin');

    }
```
That is all, let's test our work
We created some projects, 
![index with all projects](https://res.cloudinary.com/kingsconsult/image/upload/v1604701119/laravel%208%20recycle%20bin/5_ta4irg.png)
We also added a recycle icon that will take us to the page that we display all deleted projects, then we deleted two of the projects and going to the recycle page
![recycle page](https://res.cloudinary.com/kingsconsult/image/upload/v1604701078/laravel%208%20recycle%20bin/6_wd5glq.png)

![restored project](https://res.cloudinary.com/kingsconsult/image/upload/v1604701119/laravel%208%20recycle%20bin/8_atus1m.png)
These are the projects we deleted from the index page, here we have two icons, one to restore deleted projects and the other to permanently delete the project from the database 
We restored a project, and it returns to the index, then finally, we deleted the other permanently 
![permanently deleting a project](https://res.cloudinary.com/kingsconsult/image/upload/v1604701119/laravel%208%20recycle%20bin/9_dcouj6.png)

You can get the complete code from the [Github repo](https://github.com/Kingsconsult/laravel_8_recycle_bin).
Follow me for more of my articles, you can leave comments, suggestions, and reactions.
I am open to any vacancy as a PHP backend engineer, my strength is in the Laravel framework 

[click the link to view my profile and follow me] (https://dev.to/kingsconsult)