На уровне БД (конкретно в MySQL) такое реализовать нельзя, нужно эту логику закладывать в приложение.
UPD: выше написана ерунда, читайте комментарии к ответу.
Примерно так это будет выглядеть (код из живого проекта, поэтому сущности другие, но смысл тот же):
class UniqueAmongActiveClients implements \Illuminate\Contracts\Validation\Rule
{
public function passes($attribute, $value): bool
{
return Client::shouldBeUniqueAndItIs($attribute, $value, auth()->id());
}
}
class Client extends Eloquent
{
public static function shouldBeUniqueAndItIs(string $attribute, $value, ?int $excludedId = null): bool
{
$query = static::withoutTrashed()->where($attribute, $value);
if ($excludedId) {
$query->where('id', '<>', $excludedId);
}
return $query->doesntExist();
}
}
P.S. Стандартное поле
deleted_at
заменять костылями, как советуют в соседних ответах, конечно, не нужно.