Условное уникальное ограничение с Doctrine

avatar
kaan_a
8 августа 2021 в 18:03
65
1
0

У меня есть проект Laravel 8, в котором пользователи должны подтвердить свою электронную почту. Подтвержденные электронные письма должны быть уникальными. Это означает, что никто не сможет зарегистрироваться с адресом электронной почты, если кто-то уже подтвердил, что он владеет этим адресом (users.email_verified_at не NULL). Однако, если никто еще не подтвердил адрес электронной почты, допускается несколько пользовательских записей для адреса электронной почты.

В более ранних итерациях это реализовано не полностью и содержало простое уникальное ограничение при миграции:

Schema::create('users', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->string('email')->unique();
    // ...
});

А также для валидатора для регистрации пользователя:

Validator::make($data, [
    'email' => 'required|string|email|max:255|unique:users',
    // ...
]);

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

Validator::make($data, [
    'email' => [
        'required', 'string', 'email', 'max:255',
        Rule::unique('users')->where(function ($query) {
            return $query->whereNotNull('email_verified_at');
        })
    ],
    // ...
]);

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

Schema::table('users', function (Blueprint $table) {
    $table->dropUnique('users_email_unique');
});

Поэтому мой вопрос:

Можно ли с помощью Doctrine воспроизвести логику второго валидатора на уровне БД, или мне придется полагаться на необработанные операторы базы данных?

Источник

Ответы (1)

avatar
kaan_a
10 августа 2021 в 10:03
0

Согласно обсуждениям на Github Doctrine, я решил, что ответ на этот вопрос будет следующим: нет, в настоящее время нет возможности установить триггеры с помощью Doctrine, поскольку реализации в разных системах баз данных слишком сильно различаются.