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, the repo
If you prefer videos, you can watch the video from Youtube
Click on my profile to follow me to get more updates.
Step 1: Setup the app
- git clone https://github.com/Kingsconsult/laravel_8_crud.git
- cd laravel_8_crud/
- composer install
- npm install
- cp .env.example .env
- php artisan key:generate
- Add your database config in the .env file (you can check my articles on how to achieve that)
- php artisan migrate
- php artisan serve (if the server opens up, http://127.0.0.1:8000, then we are good to go)
- 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.
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
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
Going to our database, you will see the new column created with values Null
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,
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
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
You can get the complete code from the Github repo.
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
Top comments (2)
Very helpful,
Thanks
thanks alot this is helpful