Laravel 具有 id 的唯一数组验证

Laravel Array Validation Unique with an id

在使用 id 参数更新数据时如何使用 unique 验证规则,以便在仅保存现有值时验证不会失败?

'columns.*.name' => 'required|unique:columns, name, id, columns.id'

id 需要替换为数组中 * 的值,但我不知道如何替换。

你可以使用这样的东西

namespace App\Validations;

class ClientValidation
{

/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public static function rules($client_id = "")
{
    return [
        'email'          => 'required|email|unique:shippers,email,'. $client_id,
        'first_name'     => 'required',
        'last_name'      => 'required',
        'company'        => 'required',
        'phone'          => 'required',
        'password'       => 'required',
    ];
}

/**
 * Get the specific message for rules that apply to the request.
 *
 * @return array of message
 */
public static function messages()
{
    return [
        //
    ];
}

}

这是我的自定义验证,因此您需要制作文件夹并将其放入其中..

使用模型id作为唯一规则的第三个参数来跳过当前记录:

public function rules()
{
    $id = $this->route('model')->id;

    return [
        'columns.*.name' => "required|unique:columns,name,{$id}"
    ];
}

如果您在创建和更新模型时使用相同的表单请求class,请先检查这是否是补丁请求:

$id = $this->method() == 'PATCH' ? $this->route('model')->id : null;

如果您不使用路由模型绑定,请将 'model' 替换为您传递给路由的任何内容,实例化模型并传递其 ID。

我最终实施了一个更复杂的解决方案,我认为它涵盖了所有可能发生的情况。

我列出了数据库中给定列的所有当前值,包括限制 where 子句(这应该是可选的,但目前不是)。

然后我覆盖请求中包含的任何值。

最后我计算每个值在请求中使用的次数,并检查当前值是否被使用超过一次。

这可能会为每个重复值引发多次验证失败,但我认为这不是问题。

<?php

namespace App\Providers;

use DB;
use Validator;

use Illuminate\Support\ServiceProvider;

class ValidationServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {

        Validator::extend('array_unique', function($attribute, $value, $parameters, $validator) {
            $table = $parameters[0];
            $column = $parameters[1];
            $ref = $parameters[2];
            $id = $parameters[3];

            $values = DB::table($table)->where($ref, $id)->pluck($column, 'id');

            $attributes = explode(".", $attribute);
            $data = $validator->getData();

            $items = $data[$attributes[0]];

            foreach($items as $key => $item)
            {
                $values[$key] = $item[$attributes[2]];
            }

            $counts = array_count_values($values);

            return $counts[$value] < 2;
        });
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}