Подтвердить что ты не робот

Laravel: проверка уникальности при обновлении

Я знаю, что этот вопрос задавался много раз, но никто не объясняет, как получить идентификатор, когда вы проверяете модель.

'email' => 'unique:users,email_address,10'

Мое правило проверки правильности находится в модели, поэтому как передать идентификатор записи правилу проверки.

Вот мои модели/Пользователь

protected $rules_update = [
    'email_address' => 'required|email|unique:users,email_address,'.$id,
    'first_name' => "required",
    'last_name' => "required",
    'password' => "required|min:6|same:password_confirm",
    'password_confirm' => "required:min:6|same:password",
    'password_current' => "required:min:6"
];

модели/BaseModel

    protected $rules = array();

public $errors;

/*
    * @data: array, Data to be validated
    * @rules: string, rule name in model 
*/

public function validate($data, $rules = "rules") {

    $validation  = Validator::make($data, $this->$rules);

    if($validation->passes()) {
        return true;
    }

    $this->errors = $validation->messages();

    return false;
}
4b9b3361

Ответ 1

Одно простое решение.

В вашей модели

protected $rules = [
    'email_address' => 'sometimes|required|email|unique:users',
    ..
];

В вашем контроллере действие: обновить

...
$rules = User::$rules;
$rules['email_address'] = $rules['email_address'] . ',id,' . $id;
$validationCertificate  = Validator::make($input, $rules); 

Ответ 2

Просто примечание, большинство ответов на этот вопрос говорят о email_address, в то время как во встроенной системе аутентификации Laravel имя поля электронной почты просто email. Вот пример того, как вы можете проверить уникальное поле, например, электронное письмо об обновлении:

В запросе формы вам нужно сделать следующее:

public function rules()
{
  return [
      'email' => 'required|email|unique:users,email,'.$this->user->id,
  ];
}

Или если вы проверяете свои данные непосредственно в контроллере:

public function update(Request $request, User $user)
{
  $request->validate([
      'email' => 'required|email|unique:users,email,'.$user->id,
  ]);
}

Update: Если вы обновляете зарегистрированного пользователя и не внедряете модель User в свой маршрут, вы можете столкнуться с неопределенным свойством при доступе к id в $this->user. В этом случае используйте:

public function rules()
    {
      return [
          'email' => 'required|email|unique:users,email,'.$this->user()->id,
      ];
    }

Более элегантный способ, начиная с Laravel 5.7:

public function rules()
{
    return [
        'email' => ['required', 'email', \Illuminate\Validation\Rule::unique('users')->ignore($this->user()->id)]
    ];
}

П.С.: Я добавил некоторые другие правила, например, обязательные и по электронной почте, чтобы этот пример был понятен новичкам.

Ответ 3

Существует элегантный способ сделать это. Если вы используете контроллеры ресурсов, ваша ссылка для редактирования вашей записи будет выглядеть так:

/users/{user}/edit ИЛИ/users/1/edit

И в вашем UserRequest правило должно быть таким:

public function rules()
{
    return [
        'name' => [
            'required',
            'unique:users,name,' . $this->user
        ],
    ];
}

Или, если ваша ссылка для редактирования вашей записи выглядит следующим образом:

/пользователей/редактирование/1

Вы также можете попробовать:

public function rules()
{
    return [
        'name' => [
            'required',
            'unique:users,name,' . $this->id
        ],
    ];
}

Ответ 4

Если я понимаю, чего вы хотите:

'email' = > 'required | email | unique: users, email_address,'. $id. ''

В методе обновления модели, например, должен получить $id с параметром.

Извини, мой плохой английский.

Ответ 6

public function rules()
{

    switch($this->method())
    {
        case 'GET':
        case 'DELETE':
        {
            return [];
        }
        case 'POST':
        {
            return [
                'name' => 'required|unique:permissions|max:255',
                'display_name' => 'required',
            ];
        }
        case 'PUT':
        case 'PATCH':
        {
            return [                    
                'name' => 'unique:permissions,name,'.$this->get('id').'|max:255',
                'display_name' => 'required',
            ];
        }
        default:break;
    }    
}

Ответ 7

$rules = [
    "email" => "email|unique:users, email, '.$id.', user_id"
];

In Illateate\Validation\Rules\Unique;

Уникальная проверка будет анализировать проверку строки для объекта правила

Проверка уникальности имеет шаблон: unique:% s,% s,% s,% s,% s '

Соответствует: имени таблицы, столбцу, игнорированию, столбцу идентификатора, формату

/**
 * Convert the rule to a validation string.
 *
 * @return string
 */
public function __toString()
{
    return rtrim(sprintf('unique:%s,%s,%s,%s,%s',
        $this->table,
        $this->column,
        $this->ignore ?: 'NULL',
        $this->idColumn,
        $this->formatWheres()
    ), ',');
}

Ответ 8

еще более простое решение, протестированное с версией 5.2

в вашей модели

// validator rules
public static $rules = array(
    ...
    'email_address' => 'email|required|unique:users,id'
);

Ответ 9

Нашел самый простой способ, отлично работает, пока я использую Laravel 5.2

public function rules()

{

switch ($this->method()) {
    case 'PUT':
        $rules = [
            'name'                  => 'required|min:3',
            'gender'                => 'required',
            'email'                 => 'required|email|unique:users,id,:id',
            'password'              => 'required|min:5',
            'password_confirmation' => 'required|min:5|same:password',
        ];
        break;

    default:
        $rules = [
            'name'                  => 'required|min:3',
            'gender'                => 'required',
            'email'                 => 'required|email|unique:users',
            'password'              => 'required|min:5',
            'password_confirmation' => 'required|min:5|same:password',
        ];
        break;
}

return $rules;
}

Ответ 10

я бы решил это, сделав что-то вроде этого

public function rules()
{
    return [
         'name' => 
            'required|min:2|max:255|unique:courses,name,'.\Request::get('id'),
    ];
}

Где взять идентификатор из запроса и передать его по правилу

Ответ 11

Это то, что я закончил делать. Я уверен, что есть более эффективный способ сделать это, но это то, что я придумал.

Модель/User.php

protected $rules = [
    'email_address' => 'sometimes|required|email|unique:users,email_address, {{$id}}',
];

Модель/BaseModel.php

public function validate($data, $id = null) {


      $rules = $this->$rules_string;

     //let loop through and explode the validation rules
     foreach($rules as $keys => $value) {

        $validations = explode('|', $value);

        foreach($validations as $key=>$value) {

            // Seearch for {{$id}} and replace it with $id
            $validations[$key] = str_replace('{{$id}}', $id, $value);

        }
        //Let create the pipe seperator 
        $implode = implode("|", $validations);
        $rules[$keys] = $implode;

     }
     ....

  }

Я передаю $user_id для проверки в контроллере

Контроллер/UserController.php

public function update($id) { 

   .....

    $user = User::find($user_id);

    if($user->validate($formRequest, $user_id)) {
      //validation succcess 
    } 

    ....


}

Ответ 12

Мое решение:

$rules = $user->isDirty('email') ? \User::$rules : array_except(\User::$rules, 'email');

Затем в валидации:

$validator = \Validator::make(\Input::all(), $rules, \User::$messages);

Логика заключается в том, что если адрес электронной почты в форме отличается, нам нужно проверить его, если письмо не изменилось, нам не нужно проверять, поэтому удалите это правило из проверки.

Ответ 13

$validator = Validator:: make (           массив (             'Электронная почта' = > $запрос [ 'электронная почта'],            ),           массив (             'E-mail' = > 'required | email | unique: users, email,'. $Request ['id'],            ));

Ответ 14

'email' = > 'required | email | unique: users, email_address,'. $id.'ID '

Где ID является основным идентификатором таблицы

Ответ 15

При обновлении любого существующего валидатора записи данных:

'email' => ['required','email', Rule::unique('users')->ignore($user->id)]

Это будет пропускать/игнорировать сопоставление уникального значения идентификатора пользователя для конкретного столбца.

Ответ 16

Для правила unique в контроллере, которое, очевидно, будет отличаться для метода store и метода update, я обычно делаю в контроллере функцию для rules, которая возвращает массив правил.

protected function rules($request)
{
    $commonRules = [
        'first_name' => "required",
        'last_name' => "required",
        'password' => "required|min:6|same:password_confirm",
        'password_confirm' => "required:min:6|same:password",
        'password_current' => "required:min:6"
    ];

    $uniqueRules = $request->id

          //update
        ? ['email_address' => ['required', 'email', 'unique:users,email' . $request->get('id')]]

          //store
        : ['email_address' => ['required', 'email', 'unique:users,email']];


    return array_merge($commonRules, $uinqueRules);
}

Затем в соответствующих методах store и update

$validatedData = $request->validate($this->rules($request));

Это избавляет от определения двух разных наборов правил для методов хранения и обновления.

Если вы можете позволить себе немного скомпрометировать читабельность, это также может быть

protected function rules($request)
{
    return [
        'first_name' => "required",
        'last_name' => "required",
        'password' => "required|min:6|same:password_confirm",
        'password_confirm' => "required:min:6|same:password",
        'password_current' => "required:min:6",
        'email_address' => ['required', 'email', 'unique:users,email' . $request->id ?: null]
    ];
}