【问题标题】:Invalid unique validation with additive user_id field带有附加 user_id 字段的唯一验证无效
【发布时间】:2020-07-11 16:21:55
【问题描述】:

在 Laravel 6 中,我有表 sda_user_props :

id  int(10) unsigned Auto Increment 
user_id int(10) unsigned    
name    varchar(50) 
value   varchar(255)    
created_at  timestamp [CURRENT_TIMESTAMP]

其中 name 对于任何 user_id 都是唯一的,并且在请求中我将用户添加到 Model Method,它返回 规则 app/Http/Requests/UserPropRequest.php:

<?php

namespace App\Http\Requests;

use Auth;
use Illuminate\Foundation\Http\FormRequest;
use App\UserProp;

class UserPropRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        $request= Request();
        $loggedUser      = Auth::guard('api')->user();
        return UserProp::getUserPropValidationRulesArray( ($loggedUser->id ?? null), $request->get('id'), ['user_id'] );
    }
}

在我定义的模型中:

    public static function getUserPropValidationRulesArray( $user_id, $user_prop_id = null, array $skipFieldsArray= []) : array
    {

        $validationRulesArray = [
            'user_id'    => 'required|exists:'.( with(new User)->getTable() ).',id',
            'name'       => 'required|max:50|unique:'.( with(new UserProp)->getTable() ).',user_id,'.$user_id.'|unique:user_props,name,'.$user_prop_id,
            'value'        => 'required|max:255',
        ];

        foreach( $skipFieldsArray as $next_field ) {
            if(!empty($validationRulesArray[$next_field])) {
                unset($validationRulesArray[$next_field]);
            }
        }
        return $validationRulesArray;
    }

我的验证无法正常工作,我看到了跟踪 sql:

   SELECT count(*)     AS aggregate 
    FROM `sda_user_props` 
    WHERE `user_id` = 'name1'     AND `id` <> '1' 

如果我输入了“name1”的值。

看起来规则“名称”无效,但哪个有效?

修改: 那是行不通的 规则定义为:

$userTable = with(new User)->getTable();
$userPropTable = with(new UserProp)->getTable();
$validationRulesArray = [
    'user_id' => ['required', "exists:{$userTable},id"],
    'name' => ['required', 'max:50'],
    'value' => ['required', 'max:255'],
];

$validationRulesArray['name'][] =
    Rule::unique($userPropTable)->ignore($user_id, 'user_id')
       ->where(function ($query) use ($user_prop_id) {
           return $query->where('name', $user_prop_id);
       });

我记录规则数组:

array (
  'user_id' => 
  array (
    0 => 'required',
    1 => 'exists:users,id',
  ),
  'name' => 
  array (
    0 => 'required',
    1 => 'max:50',
    2 => 
    Illuminate\Validation\Rules\Unique::__set_state(array(
       'ignore' => 1,
       'idColumn' => 'user_id',
       'table' => 'user_props',
       'column' => 'NULL',
       'wheres' => 
      array (
      ),
       'using' => 
      array (
        0 => 
        Closure::__set_state(array(
        )),
      ),
    )),
  ),
  'value' => 
  array (
    0 => 'required',
    1 => 'max:255',
  ),
)  

我看到无效的 sql:

   SELECT count(*)     AS aggregate 
    FROM `sda_user_props` 
    WHERE `name` = 'A'     AND `user_id` <> '1'     AND (`name` is null) 

我想一定是条件

`user_id` == '1'  // not <>

这是什么条件:

AND (`name` is null) 

'A' - 输入文本和 user_id==1

谢谢!

【问题讨论】:

  • 您希望name user_id 的组合在一起是唯一的吗?因为我看到您在 name 属性上有两个唯一规则。
  • No 必须是 1 条规则:uniqeu 用于一对字段:user_id=>name。哪个是有效的语法?
  • 你把我弄糊涂了。这听起来像你在说我在说什么,但不同。您希望名称与 user_id 一起是唯一的,而不是它们本身都是唯一的?
  • 是的,该表在字段 user_id, name 上有唯一索引

标签: laravel eloquent


【解决方案1】:

首先将您的规则放入数组中,这样更容易使用它们。然后使用 Rule 类方法通过 where 子句定义唯一性:

$userTable = with(new User)->getTable();
$userPropTable = with(new UserProp)->getTable();
$validationRulesArray = [
    'user_id' => ['required', "exists:{$userTable},id"],
    'name' => ['required', 'max:50'],
    'value' => ['required', 'max:255'],
];

$validationRulesArray['name'][] = Rule::unique($userPropTable)->ignore($user_id, 'user_id')
    ->where(function ($query) use ($user_prop_id) {
        return $query->where('name', $user_prop_id);
}); 

【讨论】:

  • 请看 MODIFIED 块
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-24
  • 2011-08-07
  • 2017-05-29
  • 2014-03-09
  • 1970-01-01
相关资源
最近更新 更多