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;
}
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);
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
],
];
}
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.
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.
À 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),
],
]);
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;
}
}
$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()
), ',');
}
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'
);
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;
}
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.
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.
$ validator = Validator :: make ( array ( 'E-mail' => $ request ['email'], ), array ( 'E-mail' = > 'required | email | unique: utilisateurs, email,'. $ request ['id'], ));
'email' => 'obligatoire | email | unique: utilisateurs, email_address,'. $ id .'ID '
Où ID est l'id primaire de la table
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
}
....
}