Last active
September 27, 2023 05:11
-
-
Save snipe/e9143499d75fd6dce7031497d619a966 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
* Use Case: | |
* You have multiple deleted_at items that share an attribute that is supposed to be unique, | |
* for example, a username in a user's table, and are using model-level validation and watson/validation | |
* | |
* In this use case, you want to ignore ALL deleted items when considering uniqueness. | |
* | |
* The current `unique` validation rule doesn't seem to do this, even when you add the extra | |
* columns and ignored fields, e.g.: | |
* | |
* 'username' => 'required|string|min:2|unique:users,username,NULL,deleted_at', | |
* | |
* Let's say our username is 'snipe'. | |
* | |
* If you have ONE deleted user with the username 'snipe', this will pass validation. | |
* | |
* If you have MORE THAN ONE deleted user with the username 'snipe', this will fail validation | |
* disallowing any new user's with that username to be saved. This is obviously a problem, since | |
* that user will never be able to be saved since it inherently breaks Laravel's built-in | |
* `unique` validation. | |
* | |
* Using this custom validator, we would use this as the validation rule: | |
* | |
* 'username' => 'required|string|min:2|unique_undeleted', | |
* | |
* where the field following `unique_undeleted:` is the table name we should be querying | |
* the attribute name against. | |
* | |
* This code would go in the AppServiceProvider, in the `boot()` method. | |
* | |
* You'll need to add an entry into the `validation.php` language file, like: | |
* "unique_undeleted" => "The :attribute must be unique.", | |
* | |
*/ | |
// In AppServiceProvider.php | |
Validator::extend('unique_undeleted', function($attribute, $value, $parameters, $validator) { | |
$count = DB::table($parameters[0])->select('id')->where($attribute,'=',$value)->whereNull('deleted_at')->where('id','!=',$parameters[1])->count(); | |
if ($count < 1) { | |
return true; | |
} else { | |
return false; | |
} | |
}); | |
// In app/Http/Traits/UniqueUndeletedTrait.php | |
<?php | |
namespace App\Http\Traits; | |
trait UniqueUndeletedTrait | |
{ | |
/** | |
* Prepare a unique_ids rule, adding a model identifier if required. | |
* | |
* @param array $parameters | |
* @param string $field | |
* @return string | |
*/ | |
protected function prepareUniqueUndeletedRule($parameters, $field) | |
{ | |
// Only perform a replacement if the model has been persisted. | |
if ($this->exists) { | |
return 'unique_undeleted:'.$this->table.','. $this->getKey(); | |
} | |
return 'unique_undeleted:'.$this->table.',0'; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment