web-dev-qa-db-fra.com

Laravel: Validation unique lors de la mise à jour

Je sais que cette question a déjà été posée à plusieurs reprises, mais personne n’explique comment obtenir l’identifiant lors de la validation du modèle.

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

Ma règle de validation est dans le modèle, alors comment puis-je transmettre l'ID de l'enregistrement à la règle de validation.

Voici mes modèles/utilisateur

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"
];

modèles/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;
}
21
user742736

Une solution simple.

Dans votre modèle

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

Dans votre contrôleur, action: update

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

Il y a une manière élégante de faire ceci. Si vous utilisez des contrôleurs de ressources, votre lien pour modifier votre enregistrement se présentera comme suit:

/ users/{user}/editOU/ users/1/edit

Et dans votre UserRequest, la règle devrait être comme ceci:

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

Ou si votre lien pour éditer votre enregistrement ressemble à ceci:

/ utilisateurs/edit/1

Vous pouvez aussi essayer ceci:

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

Juste une note de côté, la plupart des réponses à cette question parlent de email_address alors que dans le système d'authentification intégré de Laravel, le nom du champ de courrier électronique est simplement email. Voici un exemple de validation d’un champ unique, c’est-à-dire un email sur la mise à jour:

Dans un Demande de formulaire , vous faites comme ceci:

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

Ou si vous validez vos données directement dans un contrôleur:

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

P.S: J’ai ajouté quelques autres règles, obligatoires et email, afin de rendre cet exemple clair pour les débutants.

4
Rehmat

Si je comprends ce que tu veux:

'email' => 'obligatoire | email | unique: utilisateurs, email_address,'. $ id. ''

Dans la méthode de mise à jour du modèle, par exemple, devrait recevoir le $ id avec le paramètre.

Excusez mon anglais. 

4
Lucas

À partir de Laravel 5.7, cela fonctionne très bien

use Illuminate\Validation\Rule;

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

Forcer une règle unique à ignorer un identifiant donné:

2
user2297203
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;
    }    
}
2
Janak Bhatta
$rules = [
    "email" => "email|unique:users, email, {{$id}}, user_id"
];

Dans Illuminate\Validation\Rules\Unique;

La validation unique analysera la validation de chaîne en objet Rule

La validation unique a un motif: unique:% s,% s,% s,% s,% s '

Correspondant à: nom de la table, colonne, ignorer, colonne id, format où

/**
 * 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()
    ), ',');
}
2
thenguyenit

une solution encore plus simple testée avec la version 5.2

dans ton modèle 

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

J'ai trouvé le moyen le plus simple de travailler correctement lorsque j'utilise 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;
}
1
zarpio

Lors de la mise à jour d'un validateur d'écriture de données existant comme suit:

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

Cela ignorera/ignorera la valeur unique de l'id de l'utilisateur existant correspondant à la colonne spécifique.

0
Saiful Islam

Ma solution:

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

Puis en validation:

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

La logique est que si l'adresse électronique dans le formulaire est différente, nous devons la valider, si l'e-mail n'a pas changé, nous n'avons pas besoin de valider, alors supprimez cette règle de la validation.

0
Silver Paladin

$ validator = Validator :: make ( array ( 'E-mail' => $ request ['email'], ), array ( 'E-mail' = > 'required | email | unique: utilisateurs, email,'. $ request ['id'], ));

0
Anbarasi Selvaraj

'email' => 'obligatoire | email | unique: utilisateurs, email_address,'. $ id .'ID '

Où ID est l'id primaire de la table

0
Sonam Tomar

C'est ce que j'ai fini par faire. Je suis sûr qu'il existe un moyen plus efficace de le faire, mais c'est ce que j'ai proposé.

Model/User.php

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

Model/BaseModel.php

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


      $rules = $this->$rules_string;

     //let's 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's create the pipe seperator 
        $implode = implode("|", $validations);
        $rules[$keys] = $implode;

     }
     ....

  }

Je passe le $ user_id à la validation dans le contrôleur

Controller/UserController.php

public function update($id) { 

   .....

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

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

    ....


}
0
user742736