Laravel

Laravel – Unique validation among non-deleted items with soft delete

Share your learning

Hey, dude, if you wanna know about laravel unique validation with soft delete then you are at the right place.

If you have added soft deleted to your laravel models and now have some unique columns in your database table. Then it can create an issue for you.

What is the scenario?

Let’s suppose you have unique tokens in your table. Now you just delete the one record from your table. After this if you try to add the new record with the same token which you have just deleted then it will give you an error.

“The record is already existed. “

What happened behind the scene?

Here is what happened. By default for unique validation it just checks the whole table with trashed (soft deleted) records. 

But we want to check only non-deleted records or the records which are not soft deleted and available to use.

What can we do (Solutions)?

  1. We have to tell the validation rules that check the only records which are deleted_at = Null for unique validation. By doing this we can leave the trashed records.
  2. Another thing which we can do that is add the prefix or suffix to the deleted records unique columns e.g. deleted_xyzabc or xyzabc_deleted.
    For this we can use Laravel observers, I’ll explain later in this article.
  3. If you know any other and more useful solution for this problem, please comment below.

What is the first Solution for it (Example)?

First example to use Laravel unique validation with soft delete is using Form Requests.

<?php
  
namespace App\Http\Requests;
  
use Illuminate\Foundation\Http\FormRequest;
  
class UserTokensRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */    public function authorize()
    {
        return true;
    } 
  
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */    public function rules()
    {
        return [
                'user_id' => 'required',
                'token'=>'required|unique:user_tokens,token,{$this->id},id,deleted_at,NULL'
            ];
    }
}

If you wanna use Rule facades you can replace the token line with below code.

'token' => ['required', Rule::unique('user_tokens')->ignore($this->id)->whereNull('deleted_at')] 

What SQL Queries does?

  1. When we just simply add the unique validation rule to our data, it will run the following SQL query.
SELECT
  COUNT(*) AS aggregate
FROM user_tokens
WHERE
          token = ‘xyzabc’ 
  AND id <> 1 or Null;

As you can see in the above query it will check all records of the table including soft deleted records.

2. But after implementing this solution the below query will be run where it will check the deleted_at column to identify the deleted records.

SELECT
  COUNT(*) AS aggregate
FROM user_tokens
WHERE
          token = ‘xyzabc’ 
  AND id <> 1 or Null
  AND deleted_at IS NULL;

What could be the second solution?

So, you wanna know the second solution to get rid of this laravel unique validation with soft delete issue.

For this follow the below steps

  1. Create the Observer
php artisan make:observer <observerName> -m <ModelName>;

It will create the observer and attach the models to each event. After this don’t forget to correct the model namespace if you have models in another directory.

Our example,

php artisan make:observer UserTokenObserver -m UserToken
  1. Go to the App\Providers\EventServiceProvider and in the boot method add the below code. It will connect the observer to your model.
public function boot()
{
   Model::observe(ModelObserver::class);
}

Replace the Model with your model name ModelObserver with your model observer and make sure the namespace should be correct for both model and model observer. 

Our example,

Use App\Model\UserToken;
Use App\Observers\UserTokenObserver;

class EventServiceProvider extends ServiceProvider
{
  /**
  * Register any events for your application.
  *
  * @return void
  */  public function boot()
  {
    UserToken::observe(UserTokenObserver::class);
  }
}
  1. Now, when you perform the delete action it will trigger the deleting and deleted events of the observer. But we just need a deleting method for the time.
<?php

namespace App\Observers;

Use App\Model\UserToken;

class UserTokenObserver
{
    /**
     * Handle the UserToken "created" event.
     *
     * @param  \App\UserToken  $userToken
     * @return void
     */    public function created(UserToken $userToken)
    {
        //
    }

    /**
     * Handle the UserToken  "updated" event.
     *
     * @param  \App\UserToken  $userToken
     * @return void
     */    public function updated(UserToken $userToken)
    {
        //
    }

    /**
     * Handle the UserToken "deleted" event.
     *
     * @param  \App\UserToken  $userToken
     * @return void
     */    public function deleted(Service $service)
    {
      
    }

    public function deleting(UserToken $userToken) {
        $userToken->token = 'deleted_'.$userToken->token;
        $userToken->save();
     }


    /**
     * Handle the UserToken "restored" event.
     *
     * @param  \App\UserToken  $userToken
     * @return void
     */    public function restored(Service $service)
    {
        //
    }

    /**
     * Handle the UserToken "force deleted" event.
     *
     * @param  \App\UserToken  $userToken
     * @return void
     */    public function forceDeleted(Service $service)
    {
        //
    }
}

That’s it, 

How to use laravel unique validation with soft delete.

Hope you find this article useful. See you in the next learning chapter.

Satpal

Recent Posts

How to Switch PHP Versions in XAMPP Easily: Managing Multiple PHP Versions on Ubuntu

Today we are going to learn about managing multiple PHP versions on ubuntu with xampp.…

1 year ago

How to Use Coding to Improve Your Website’s SEO Ranking?

Let's understand about how to use coding to improve your website's SEO. In today’s computerized…

1 year ago

Most Important Linux Commands for Web Developers

Let's understand the most important linux commands for web developers. Linux, as an open-source and…

1 year ago

Top 75+ Laravel Interview Questions Asked by Top MNCs

Today we are going to discuss top 75+ Laravel interview questions asked by top MNCs.Laravel,…

1 year ago

Mailtrap Integration for Email Testing with Laravel 10

Today we will discuss about the Mailtrap integration with laravel 10 .Sending and receiving emails…

1 year ago

Firebase Cloud Messaging (FCM) with Ionic 6: Push Notifications

Today we are going to integrate FCM (Firebase Cloud Messaging) push notifications with ionic application.Firebase…

1 year ago