带有附加user_id字段的无效唯一验证

时间:2020-03-31 07:08:34

标签: laravel eloquent

在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]

其中名称对于任何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

谢谢!

1 个答案:

答案 0 :(得分: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);
});