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()
{
//
}
}
在使用 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()
{
//
}
}