Уникальное поле запроса Laravel обновляется, только если оно изменено

Я не могу подтвердить адрес электронной почты пользователя при определенных обстоятельствах.

Например

If a user is being created, the email address must be unique

If a user is being updated but the email address hasn't changed, ignore the unique email rule

If a user is being updated and their email address has changed, it has to be unique

Я немного осмотрелся и знаю, что могу указать разные правила на основе такого метода

public function rules()
{
    $user = User::find($this->users);

    switch($this->method())
    {
        case 'POST':
        {
            return [
                'user.email'      => 'required|email|unique:users,email',
            ];
        }
        case 'PUT':
        case 'PATCH':
        {
            return [
                'user.email'      => 'required|email,
            ];
        }
        default:break;
    }
}

Есть ли способ сделать так, чтобы в случае put / patch правило проверяло, был ли изменен адрес электронной почты, и если это так, то он должен быть уникальным?

Если нет, есть ли более чистый способ достижения этой цели? Может без корпуса переключателя? Возможно, я еще не наткнулся на более подробные правила проверки?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
5
6 814
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

В методах вашего контроллера (сохранение и обновление) вы можете использовать:

 $validations = [
        'email'                 => 'required|email|unique:users,email'
    ];

 $this->validate($request, $validations);

Вам не хватает оператора break; после каждого case.. И для обновления (запрос PATCH) вы должны передать id также в запросе на обновление.

public function rules()
{
    $user = User::find($this->users);

    switch($this->method())
    {
        case 'PATCH':
        {
            return [
                'user.email'      => 'required|email|unique:users,email,'. $user->id.',id',
            ];
        }
        break; // change here
        case 'PUT': break; // change here
        case 'POST':
        {
            return [
                'user.email'      => 'required|email,
            ];
        }
        break; // change here
        default:break;
    }
}

Для этого есть встроенная функция. Вы можете добавить фактический идентификатор пользователя к уникальному ограничению, если оно есть. Это гарантирует, что ограничение уникальности по-прежнему будет работать, но оно не завершится ошибкой, если значение не изменилось:

$exists = $user->exists;
$rules = return [
    'user.email' => 'required|email|unique:users,email' . ($exists ? ','.$user->id : ''),
];

Внутри это выполнит такой запрос:

SELECT count(id) FROM users WHERE email = '[email protected]' AND id != 42

Последняя часть AND id != 42 будет только частью запроса, когда вы добавите третий параметр в уникальное правило проверки.

Ответ принят как подходящий

Если я вас правильно понимаю, вы хотите добавить проверку unique, если адрес электронной почты изменился, в этом случае вам просто нужно добавить условие в проверку. Если вы проверяете уникальную структуру проверки, она выглядит как unique:table,column,except,idColumn, проверьте документация

Таким образом, проверка будет выглядеть так: когда вы создадите новую запись, $userId будет иметь значение null, но во время исправления он будет иметь значение. Таким образом, эта проверка будет работать как для создания, так и для исправления.

$userId = isset($user) ? $user->id : null;

$rules = [
        'email' => 'required|email|unique:users,email,'. $userId.',id',
    ];

 $this->validate($request, $rules);
$request->validate([
        'naam' => 'required|max:190|unique:database_name.table,column_where_you_check_unique,'.$id.',$id_column_reference'
    ]);

'naam' - имя поля ввода формы

database_name (необязательно) - если у вас несколько баз данных

table (обязательно) - название таблицы

column_where_you_check_unique (обязательно) - где данные уникальны

$ id (обязательно) - проверка с автоинкрементом id

$ id_column_reference - имя столбца $ id.

Мой метод:

'slug' => $site->slug !== $request->slug ? 'required|min:4|max:80|unique:sites' : 'required|min:4|max:80'

Вы можете попробовать это

$exists = Section::where('code', $request->code)->exists();
        $isUpdateQuery = (($request->method() == 'PUT') || ($request->method() == 'PATCH'));
        $validatedData = $request->validate([
            "code" => ['required','unique:sections,code' . (($isUpdateQuery && $exists) ? ',' . $request->code . ',code': '')],
            "title" => 'required | json',
            "subtitle" => 'required | json',
            "btn_title" => 'required | json',
            "name" => 'required',
            "pageID" => 'required | exists:pages,pageID',
            "image" => 'nullable',
            "btn_link" => 'nullable',
        ]);

У меня была аналогичная проблема, и я нашел аккуратный способ решить ее в документации.

Моя проблема заключалась в том, что если пользователь уже был создан, адрес электронной почты утверждал, что он не является уникальным, даже если он уже был зарегистрирован для пользователя.

https://laravel.com/docs/8.x/validation#rule-unique

Несколько заголовков вниз выглядят примерно так:

use Illuminate\Validation\Rule;

$request->validate([
    'email' => [
        'required',
        Rule::unique('users')->ignore($user->id),
    ],
]);

Это делает следующее:

Validate the email address, make it required and unique, unless the user ID of that row matches this user.

Другие вопросы по теме