Ich weiß, dass diese Frage schon oft gestellt wurde, aber niemand erklärt, wie man die ID erhält, wenn man im Modell validiert.
'email' => 'unique:users,email_address,10'
Meine Validierungsregel befindet sich im Modell. Wie übergebe ich die ID des Datensatzes an die Validierungsregel?
Hier sind meine Modelle / Benutzer
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"
];
Modelle / 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;
}
php
validation
laravel
laravel-4
user742736
quelle
quelle
Antworten:
Eine einfache Lösung.
In Ihrem Modell
protected $rules = [ 'email_address' => 'sometimes|required|email|unique:users', .. ];
Aktion: Update in Ihrem Controller
... $rules = User::$rules; $rules['email_address'] = $rules['email_address'] . ',id,' . $id; $validationCertificate = Validator::make($input, $rules);
quelle
Nur eine Randnotiz, die meisten Antworten auf diese Frage sprechen darüber,
email_address
während in Laravels eingebautem Authentifizierungssystem der Name des E-Mail-Feldes gerecht istemail
. Hier ist ein Beispiel, wie Sie ein eindeutiges Feld überprüfen können, dh eine E-Mail zum Update:In einer Formularanforderung gefällt Ihnen Folgendes:
public function rules() { return [ 'email' => 'required|email|unique:users,email,'.$this->user->id, ]; }
Oder wenn Sie Ihre Daten in einem Controller direkt validieren:
public function update(Request $request, User $user) { $request->validate([ 'email' => 'required|email|unique:users,email,'.$user->id, ]); }
Aktualisieren : Wenn Sie den angemeldeten Benutzer aktualisieren und das
User
Modell nicht in Ihre Route einfügen, können beim Zugriffid
auf undefinierte Eigenschaften auftreten$this->user
. Verwenden Sie in diesem Fall:public function rules() { return [ 'email' => 'required|email|unique:users,email,'.$this->user()->id, ]; }
Ein eleganterer Weg seit Laravel 5.7 ist:
public function rules() { return [ 'email' => ['required', 'email', \Illuminate\Validation\Rule::unique('users')->ignore($this->user()->id)] ]; }
PS: Ich habe einige andere Regeln hinzugefügt, z. B. Erforderlich und E-Mail, um dieses Beispiel für Neulinge deutlich zu machen.
quelle
FormRequest
, und genau das musste ich tun.\Illuminate\Validation\Rule::unique()
es ist wirklich die eleganteste Art und Weise. Für mich war das der beste Vorschlag. DankeEs gibt eine elegante Möglichkeit, dies zu tun. Wenn Sie Resource Controller verwenden, sieht Ihr Link zum Bearbeiten Ihres Datensatzes folgendermaßen aus:
Und in Ihrer UserRequest sollte die Regel folgendermaßen lauten:
public function rules() { return [ 'name' => [ 'required', 'unique:users,name,' . $this->user ], ]; }
Oder wenn Ihr Link zum Bearbeiten Ihres Datensatzes folgendermaßen aussieht:
Sie können dies auch versuchen:
public function rules() { return [ 'name' => [ 'required', 'unique:users,name,' . $this->id ], ]; }
quelle
/users/{user}/edit
und ich möchte verhindern, dass ichunique:users,name
aktualisiert werden kann, während andere Felder aktualisiert werden können. Wie würde ich es erreichen?Ab Laravel 5.7 funktioniert dies hervorragend
use Illuminate\Validation\Rule; Validator::make($data, [ 'email' => [ 'required', Rule::unique('users')->ignore($user->id), ], ]);
Erzwingen einer eindeutigen Regel zum Ignorieren einer bestimmten ID:
quelle
Wenn ich verstehe, was Sie wollen:
Bei der Modellaktualisierungsmethode sollte beispielsweise die $ id mit Parameter empfangen werden.
Entschuldigung für mein schlechtes Englisch.
quelle
Eine noch einfachere Lösung, die mit Version 5.2 getestet wurde
in Ihrem Modell
// validator rules public static $rules = array( ... 'email_address' => 'email|required|unique:users,id' );
quelle
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; } }
quelle
Test unter Code:
'email' => 'required|email|unique:users,email_address,'. $id .'ID'
Dabei ist ID die primäre ID der Tabelle
quelle
Hier ist die Lösung:
Zum Update:
public function controllerName(Request $request, $id) { $this->validate($request, [ "form_field_name" => 'required|unique:db_table_name,db_table_column_name,'.$id ]); // the rest code }
Das ist es. Viel Spaß beim Codieren :)
quelle
Ich würde das lösen, indem ich so etwas mache
public function rules() { return [ 'name' => 'required|min:2|max:255|unique:courses,name,'.\Request::get('id'), ]; }
Woher erhalten Sie die ID aus der Anfrage und geben sie an die Regel weiter?
quelle
id
Parameter etwas angibt. laravel.com/docs/5.8/validation#rule-unique$rules = [ "email" => "email|unique:users, email, '.$id.', user_id" ];
In Illuminate \ Validation \ Rules \ Unique;
Durch die eindeutige Überprüfung wird die Zeichenfolgenüberprüfung für das Regelobjekt analysiert
Die eindeutige Validierung weist ein Muster auf: eindeutig:% s,% s,% s,% s,% s '
Entspricht: Tabellenname, Spalte, Ignorieren, ID-Spalte, Format wherees
/** * 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() ), ','); }
quelle
Am einfachsten gefunden, funktioniert gut, während ich Laravel 5.2 verwende
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; }
quelle
if (in_array($this->method(), ['PUT', 'PATCH'])) { $rules['order'] .= ",{$this->route('videos')->id}"; }
Verwendung für Laravel 6.0
use Illuminate\Validation\Rule; public function update(Request $request, $id) { // Form validation $request->validate([ 'category_name' => [ 'required', 'max:255', Rule::unique('categories')->ignore($id), ] ]); }
quelle
Sie können auch den Modellklassenpfad verwenden, wenn Sie den Tabellennamen nicht fest codieren möchten.
function rules(){ return [ 'email' => ['required','string', Rule::unique(User::class,'email')->ignore($this->id)] ]; }
Hier ist $ this-> id entweder 0 oder die zu aktualisierende Datensatz-ID.
quelle
Sie können dies versuchen.
protected $rules_update = [ 'email_address' => 'required|email|unique:users,email_address,'. $this->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" ];
quelle
Das habe ich letztendlich getan. Ich bin mir sicher, dass es einen effizienteren Weg gibt, aber das habe ich mir ausgedacht.
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; } .... }
Ich übergebe die $ user_id an die Validierung im Controller
Controller / UserController.php
public function update($id) { ..... $user = User::find($user_id); if($user->validate($formRequest, $user_id)) { //validation succcess } .... }
quelle
Während der Aktualisierung eines vorhandenen Datenschreibprüfers wie folgt:
'email' => ['required','email', Rule::unique('users')->ignore($user->id)]
Dadurch wird der eindeutige Wert der vorhandenen Benutzer-ID für die jeweilige Spalte übersprungen / ignoriert.
quelle
Test unter Code:
$validator = Validator::make( array( 'E-mail'=>$request['email'], ), array( 'E-mail' => 'required|email|unique:users,email,'.$request['id'], ));
quelle
id
Parameter0|nullable
oder schlechter sein lassen). laravel.com/docs/5.8/validation#rule-uniqueDie beste Option ist hier, nur einmal zu versuchen, keinen Code mehr zu benötigen, wenn eine eindeutige Validierung beim Aktualisieren von Daten erfolgt
'email' => 'unique:users,email_address,' . $userId,
Hier
email
ist der Feldname und derusers
Tabellenname sowie deremail_address
Tabellenattributname, der eindeutig sein soll und$userid
die Zeilen-ID aktualisiertquelle
Meine Lösung:
$rules = $user->isDirty('email') ? \User::$rules : array_except(\User::$rules, 'email');
Dann zur Validierung:
Die Logik lautet: Wenn die E-Mail-Adresse im Formular unterschiedlich ist, müssen wir sie validieren. Wenn sich die E-Mail nicht geändert hat, müssen wir sie nicht validieren. Entfernen Sie diese Regel aus der Validierung.
quelle
Für
unique
Regeln in der Steuerung - die sich offensichtlich für diestore
Methode und dieupdate
Methode unterscheiden - mache ich normalerweise eine Funktion innerhalb der Steuerung, fürrules
die ein Array von Regeln zurückgegeben wird.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); }
Dann in den jeweiligen
store
undupdate
Methoden$validatedData = $request->validate($this->rules($request));
Dies erspart die Definition von zwei verschiedenen Regelsätzen für Speicher- und Aktualisierungsmethoden.
Wenn Sie es sich leisten können, bei der Lesbarkeit ein wenig Kompromisse einzugehen, kann dies auch der Fall sein
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] ]; }
quelle
id
Parameter so ändern , dass er beliebig ist. laravel.com/docs/5.8/validation#rule-uniqueIch habe den vorherigen Beitrag gelesen, aber keiner nähert sich dem eigentlichen Problem. Wir müssen die Regel eindeutig verwenden, um sie auf das Hinzufügen und Bearbeiten von Groß- und Kleinschreibung anzuwenden. Ich verwende diese Regel beim Bearbeiten und Hinzufügen von Groß- und Kleinschreibung und arbeite einwandfrei.
In meiner Lösung verwende ich die Regelfunktion aus der Anforderungsklasse.
Auf dem Code:
public function rules() { // $user = User::where('email', $this->email)->first(); // $this->id = isset($this->id) ? $this->id : null; $emailRule = (($user != null) && ($user->id == $this->id)) ? 'required|email:rfc,dns|max:255' : 'required|unique:users|email:rfc,dns|max:255'; // return [ // 'email' => $emailRule, // ]; // }
quelle
Da Sie den Datensatz, den Sie aktualisieren, bei der Durchführung eines Updates ignorieren möchten, sollten Sie ihn
ignore
wie von einigen anderen erwähnt verwenden. Aber ich bevorzuge es, eine Instanz derUser
ID zu erhalten, anstatt nur eine ID. Mit dieser Methode können Sie dies auch für andere Modelle tunRegler
public function update(UserRequest $request, User $user) { $user->update($request->all()); return back(); }
Benutzeranfrage
public function rules() { return [ 'email' => [ 'required', \Illuminate\Validation\Rule::unique('users')->ignoreModel($this->route('user')), ], ]; }
Update:
ignoreModel
anstelle von verwendenignore
quelle
Es funktioniert wie ein Zauber, den jemand ausprobieren kann. Hier habe ich Soft Delete Checker verwendet. Sie können das letzte weglassen:
id,deleted_at, NULL
Wenn Ihr Modell keine Soft-Delete-Implementierung hat.public function rules() { switch ($this->method()) { case 'PUT': $emailRules = "required|unique:users,email,{$this->id},id,deleted_at,NULL"; break; default: $emailRules = "required|unique:users,email,NULL,id,deleted_at,NULL"; break; } return [ 'email' => $emailRules, 'display_name' => 'nullable', 'description' => 'nullable', ]; }
Vielen Dank.
quelle
Nachdem ich viel zu diesem Thema der Laravel-Validierung einschließlich einer einzigartigen Spalte recherchiert hatte, bekam ich endlich den besten Ansatz. Guck dir das mal bitte an
In Ihrem Controller
use Illuminate\Http\Request; use Illuminate\Support\Facades\Validator; class UserController extends Controller { public function saveUser(Request $request){ $validator = Validator::make($request->all(),User::rules($request->get('id')),User::$messages); if($validator->fails()){ return redirect()->back()->withErrors($validator)->withInput(); } } }
saveUser
Methode kann zum Hinzufügen / Aktualisieren von Benutzerdatensätzen aufgerufen werden.In deinem Modell
class User extends Model { public static function rules($id = null) { return [ '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" ]; } public static $messages = [ 'email_address.required' => 'Please enter email!', 'email_address.email' => 'Invalid email!', 'email_address.unique' => 'Email already exist!', ... ]; }
quelle