Laravel在更新时检查唯一规则但不包括自身

66

我正在更新部分使用我的验证规则以确保唯一性。

在插入或添加时,唯一性规则为'Email' => array('unique:driver_details'),它将检查唯一列。

但是,这在更新部分失败。在更新中,它满足其他规则,并且在电子邮件的唯一性上,它正在检查自己的唯一列并失败,因为它看到了自己的字段。

那么,如何检查除了数据库中自身的值以外的唯一性?


可能是Laravel 4验证电子邮件唯一约束条件的重复问题。 - patricus
@patricus:我理解了你的问题,但是在你的回答中没有提到如何获取$id。如果他们要验证自己的个人资料,可以通过Auth::user()->id获得他们的id,对于管理员将这些部分分配给其他部分,我应该设置会话并在模型内获取吗??? - user3388086
你目前是如何获取你正在尝试更新的记录的ID的? - patricus
我正在将所有的值发送到模型,$validation = Validator::make($DriverData, DriverModel::$updaterules); - user3388086
我在这里发布了一个新问题,应该很清楚,请你看一下这里:http://stackoverflow.com/questions/28205762/how-to-pass-the-value-inside-the-model-for-checking-in-the-rules - user3388086
24个回答

92

这将强制忽略特定的id:

'email' => 'unique:table,email_column_to_check,id_to_ignore'

在上面的示例中,替换段落中的tableemail_column_to_checkid_to_ignore

您可以在此处检查:http://laravel.com/docs/4.2/validation#rule-unique


4
但是我该如何在模型中获取 id_to_ignore 呢?我无法获取 Auth::user()->id,因为这是管理员部分,而且正在对其他用户进行验证。 - user3388086
1
你可以通过以下方式从请求中获取它:request()->route('路由通配符')->id - Jelly Bean
1
如果您定义了如下路由:Route::apiresource('car', 'Api\CarController'),那么您可以通过以下方式获取资源的ID:request()->route('car') 或者 request()->route()->parameters['car']。如果您在请求对象内部,也可以使用 $this 代替 request() - totymedli

36

对于使用 Laravel 5 和表单请求的用户,您可以直接将路由模型绑定的模型 ID 作为表单请求的属性 $this->name_of_the_model->id 并使用它来从唯一规则中忽略它。

例如,如果您想要有唯一的电子邮件地址,但也允许管理员编辑用户,则可以执行以下操作:

路由:

Route::patch('users/{user}', 'UserController@update');

控制器:

public function update(UserRequest $request, User $user) 
{
    // ...
}

表单请求:

class UserRequest extends FormRequest
{
    // ...
    public function rules()
    {
        return [
            'name' => 'required|string',
            'email' => [
                'required',
                'email',
                Rule::unique('users')->ignore($this->user()->id, 'id')
            ],
            //...
        ];
    }
    //...
}
请注意,我们忽略正在被编辑的用户,这种情况下该用户可能与经过身份验证的用户不同。

可以使用Rule::unique('users')->ignoreModel($this->user) - Daniel Cheung
1
在 Laravel 9 中,Rule::unique('users')->ignoreModel($this->user()) 是正确的语法。 - senty
1
我刚刚测试了一下,它们并不相同:$this->user 返回由路由模型绑定解析的用户,而 $this->user() 返回当前用户(即与调用 auth()->user() 相同)。 - PlumsAhoy

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

4
欢迎来到StackOverflow!请考虑在您的代码中添加一些解释,以便OP和其他用户了解您的答案适用的原因和方法。 :) - Uzair A.

16

我正在使用Laravel 5.2

如果你的主键名为'id',表名为users_table,并且你想更新user_name,那么可以按照以下方式操作

'user_name'  =>  'required|unique:users_table,user_name,'.$id

如果您的主键不是以'id'命名

在我的情况下,我的主键是'user_id',表名是'users_table',并且您想要更新'user_name'

那么请按照以下方式操作

'user_name' => 'required|unique:users_table,user_name,'.$id.',user_id'

10

试试这个

'email' => 'unique:table_name,column_name,'.$this->id.',id'

$this->id 将是您请求的值。


我的问题是 $this->id 将被验证的值吗?我的意思是,如果我在 id 中传递任何字符串值,其中它是整数字段或类似 'or 1=1' 的值,会发生什么。我想知道它是否安全,可以防止 SQL 注入? - Er Jagdish Patel

7

通过书写Include规则

use Illuminate\Validation\Rule;

并且,您可以按照以下方式编写验证代码:
 'Email' => [required,
            Rule::unique('driver_details')->ignore($id),
            ]

在这里,$id是从控制器获取的要在验证过程中忽略的电子邮件的ID。

7

6

我花了一些时间才明白,但是在处理更新/创建请求时,您还可以访问请求对象。在这里,我强制执行客户端名称的唯一性,但允许当前正在编辑的客户端。

class CreateUpdateClientRequest extends FormRequest
{
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => [
                'required',
                'string',
                'min:3',
                'max:50',
                Rule::unique('clients')->ignore($this->request->get('id'))
            ],
            'primary_contact_name' => 'required|string|min:3|max:50',
            'primary_contact_email' => 'required|string|email|min:5|max:50',
            'primary_contact_phone' => 'nullable|string|min:5|max:50',
            'secondary_contact_name' => 'nullable|string|min:3|max:50',
            'secondary_contact_email' => 'nullable|string|email|min:5|max:50',
            'secondary_contact_phone' => 'nullable|string|min:5|max:50',
            'notes' => 'nullable'
        ];
    }
}

6
在 Laravel 6 应用程序中,它帮助我从验证中排除当前用户的电子邮件:
use Illuminate\Validation\Rule;

public function update(Request $request, $id)
{
    $request->validate([
        'email' => [
            'email',
            'required',
             Rule::unique('claims')->ignore($id),
        ],
    ]);

    // ...
}

2

Laravel 8:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接