Неверная уникальная проверка с аддитивным полем user_id - PullRequest
0 голосов
/ 31 марта 2020

В 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, и в запросе я добавляю пользователя в метод метода, который возвращает правила 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'.

Похоже, что правило 'name' недопустимо, но какое действительное?

ИЗМЕНЕНО: То есть не работает с правила определены как:

$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 Ответ

1 голос
/ 31 марта 2020

Сначала сделайте ваши правила в массиве, чтобы с ними было проще работать. Затем используйте метод класса 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);
}); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...