📜  如果更改此字段,则 laravel 验证唯一 - PHP (1)

📅  最后修改于: 2023-12-03 15:38:59.633000             🧑  作者: Mango

如果更改此字段,则 Laravel 验证唯一

在 Laravel 中,我们可以使用验证器来验证表单输入是否符合规定。其中一个常用的验证规则是 unique,用于验证某个字段的值在整个数据库中是否唯一。然而,在实际开发中,有时我们需要排除当前记录本身,例如在更新某个记录时,我们需要验证某个字段是否唯一,但需要排除当前记录的 ID。

本文将介绍如何实现在更新记录时,验证某个字段的值是否唯一,但需要排除当前记录的 ID,以及如何将此逻辑封装成自定义验证规则,以便于在多个地方复用。

验证规则参数

在 Laravel 中,unique 验证规则可以通过第三个参数指定要排除的记录:

$request->validate([
    'email' => 'unique:users,email_address,'.$user->id
]);

在此例中,'email' 为要验证的字段名,'users' 为要验证的表名,'email_address' 为要验证的字段名,'$user->id' 为当前记录的 ID,也就是要排除的记录。

封装自定义验证规则

为了方便在多个地方复用上述逻辑,我们可以将其封装成自定义验证规则。首先,我们需要定义一个验证器类,用于封装验证逻辑:

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;
use Illuminate\Support\Facades\DB;

class UniqueExceptSelf implements Rule
{
    protected $table;
    protected $column;
    protected $idColumn;
    protected $idValue;

    public function __construct($table, $column, $idColumn, $idValue)
    {
        $this->table = $table;
        $this->column = $column;
        $this->idColumn = $idColumn;
        $this->idValue = $idValue;
    }

    public function passes($attribute, $value)
    {
        $count = DB::table($this->table)
            ->where($this->column, $value)
            ->where($this->idColumn, '<>', $this->idValue)
            ->count();

        return $count === 0;
    }

    public function message()
    {
        return 'The :attribute has already been taken.';
    }
}

在此例中,我们定义了一个名为 UniqueExceptSelf 的类,实现了 Rule 接口,因此可以作为验证规则使用。该类包含以下属性:

  • $table:要验证的表名
  • $column:要验证的字段名
  • $idColumn:当前记录的 ID 字段名
  • $idValue:当前记录的 ID 的值

passes 方法中,我们根据上述属性执行相应的查询,从而判断该字段的值是否唯一。在 message 方法中,我们定义了当验证失败时返回的错误信息。

接下来,我们可以在表单请求中使用该验证规则:

use App\Rules\UniqueExceptSelf;

$request->validate([
    'email' => [
        'required',
        new UniqueExceptSelf('users', 'email_address', 'id', $user->id)
    ],
]);

在此例中,我们通过 new 关键字创建了一个 UniqueExceptSelf 实例,并将其作为验证规则传递给了 email 字段。这样,当 email 字段的值重复时,验证器就会返回 'The email has already been taken.' 错误信息。

如果要扩展此验证规则,例如添加可选参数来指定表名或字段名等,只需在构造方法中添加更多参数,并存储为相应属性即可。

以上介绍了如何实现在更新记录时,验证某个字段的值是否唯一,但需要排除当前记录的 ID,以及如何将此逻辑封装成自定义验证规则。这样,在实际开发中,我们就可以方便地复用该规则,避免重复编写代码。