How To Add SoftDelete With Unique Validation In Laravel

soft-delete-in-laravel

In this tutorial, I will show you how to soft delete record and unique validation in laravel.

In soft delete process, instead of actually removing records from your database, Eloquent can also “soft delete” models. When models are soft deleted, they are not actually removed from your database. Instead, a deleted_at attribute is set on the model and inserted into the database.

If a model has a non-null deleted_at value, the model has been soft deleted. To enable soft deletes for a model, use the Illuminate\Database\Eloquent\SoftDeletes trait on the model:

Open model in which you want to add soft delete. For example i am going to add soft delete in user model.

user.php

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\SoftDeletes;

class User extends Authenticatable
{
    use Notifiable, SoftDeletes;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', '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',
    ];
}

In above file we have used Illuminate\Database\Eloquent\SoftDeletes trait. Also used statement use SoftDeletes;

For below laravel 5.8 version, you have to define deleted_at column as shown below

<?php

namespace App;

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

class Flight extends Model
{
    use SoftDeletes;

    /**
     * The attributes that should be mutated to dates.
     *
     * @var array
     */
    protected $dates = ['deleted_at'];
}

For 5.8

You don’t need to define deleted_at in laravel 5.8 version. The SoftDeletes trait will automatically cast the deleted_atattribute to a DateTime / Carbon instance for you.

Now let’s open user migration file and add $table->softDeletes(); as shown below.

Related:  Laravel 6 - ONE TO ONE Eloquent Relationship With Example

xxxx_xx_xx_xxxxxx_create_users_table.php  [Where xxx stands for date time]

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
            $table->softDeletes();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}

Now fresh migration using below artisan command.

php artisan migrate:fresh

If there is no error while running above command, then check users table in database. You will see deleted_at field added in there.

soft-delete-in-laravel

Now, when you call the delete method on the model, the deleted_at column will be set to the current date and time.

<?php

namespace App\Http\Controllers;

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

class UserController extends Controller
{
    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $user = User::find($id);
        if ($user) {
            $user->delete(); // Delete user
        }
        ... // Return view code
    }
}

Retrieve Model Data

When querying a model that uses soft deletes, the soft deleted models will automatically be excluded from all query results. Below eloquent query only fetch non-deleted records automatically.

$users = User::all();

Retrieve Model Data With Soft Deleted Data

As shown above, all soft deleted models will be automatically excluded from query results. However, if you want them in query result You can use withTrashed method on query as shown below.

$users = User::withTrashed()->get();

The withTrashed method may also be used on a relationship query:

$users->addresses()->withTrashed()->get();

Retrieving Only Soft Deleted Models

The onlyTrashed method will retrieve only soft deleted data excluding non-deleted data.

$users = User::onlyTrashed()->get();

Restoring Soft Deleted Models In Un-Deleted Models

One of the best benefit of soft deleted model is we can restore them to “un-delete” state. In hard delete we can’t restore the deleted record. We can restore soft deleted model using restore method.

$user->restore();

Permanently Deleting Models

Sometimes you may need to truly remove a model from your database. To permanently remove a soft deleted model from the database, use the forceDeletemethod. This method also works on relationship model.

// Force deleting a single model instance...
$user->forceDelete();

// Force deleting all related models...
$user->history()->forceDelete();

Unique Validation With Soft Delete

Normally unique validation check unique data in non-deleted records. But after adding soft delete, there are also present many soft deleted data too. So we need to unique validation only on non-deleted data as shown below.

Related:  [SOLVED] PHP is not recognized as an internal or external command
Without Soft Delete
// On create method
'email' => 'required|unique:users,email',

// On Update Method
'email' => 'required|unique:users,email,'.$id,
With Soft Delete
// On create Method
'email' => 'required|unique:users,email,NULL,id,deleted_at,NULL',

// On Update Method
'email' => 'required|unique:users,email,'.$id.',id,deleted_at,NULL',

Final Words…

I hope that you may like how to add soft delete in laravel tutorial. Drop me comment if you have any query regarding this tutorial. Please share this on social media if you like it. Thank you 🙂

About Chintan Panchal

I am web developer having 6+ year of experience of web development. Currently working on laravel and have worked on codeigniter, cakephp, symfony. Thank you :)

View all posts by Chintan Panchal →

2 Comments on “How To Add SoftDelete With Unique Validation In Laravel”

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.