【问题标题】:Conditional unique constraint with Doctrine带有 Doctrine 的条件唯一约束
【发布时间】:2021-10-12 15:20:54
【问题描述】:

我有一个 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');
        })
    ],
    // ...
]);

这可以满足应用层的要求,但是除非从 users 表中删除唯一约束,否则它将导致引发 DB 异常:

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

因此我的问题是:

是否可以使用 Doctrine 在数据库层复制第二个验证器的逻辑,还是我必须依赖数据库特定的原始语句?

【问题讨论】:

    标签: php doctrine database-migration laravel-8


    【解决方案1】:

    根据 Doctrine 的 Github 上的讨论,我确定这个问题的答案是:不,目前没有办法用 Doctrine 设置触发器,因为不同数据库系统的实现差异太大。

    【讨论】:

      猜你喜欢
      • 2015-04-16
      • 2010-10-26
      • 2013-04-20
      • 2021-07-22
      • 2017-07-07
      • 1970-01-01
      • 2018-08-23
      • 2012-07-21
      相关资源
      最近更新 更多