2013-05-13 20 views
6

ich die folgenden Regeln für die Validierung verwenden, um einen neuen Benutzer zur Erstellung von:Laravel 4 Validierung

protected $rules= [ 
    'name' => 'required', 
    'email' => [ 
     'required', 
     'unique:user', 
     'email' 
    ] 
]; 

Wenn Sie einen vorhandenen Benutzer ich den gleichen Regelsatz verwenden Aktualisierung wie oben gezeigt, aber keine Validierungsfehler möchten, wenn die Benutzer hat seine E-Mail überhaupt nicht geändert.

ich lösen dies derzeit durch die folgende Verwendung:

if (!User::changed('email')) { 
    unset($user->email); 
} 

Es fühlt sich an wie ein schmutziges Abhilfe mir so habe ich mich gefragt, ob es bessere Alternativen gibt.

Beachten Sie auch, dass die changed Methode ist etwas, das ich selbst geschrieben habe. Weiß jemand, ob dort ist eine native Laravel 4-Methode zum Überprüfen, ob eine Modelleigenschaft geändert hat?

Danke!

+0

Hallo in dieser Frage diese meine Antwort überprüfen [http://stackoverflow.com/questions/16976207/laravel-4-validation-uniquedatabase-ignore-current][1], ich hoffe, diese Hilfe. [1]: http://stackoverflow.com/questions/16976207/laravel-4-validation-uniquedatabase-ignore-current – Bradley

Antwort

9

Die eindeutige Validierungsregel erlaubt es, eine bestimmte ID zu ignorieren, in Ihrem Fall die ID des zu aktualisierenden Datensatzes.

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

http://four.laravel.com/docs/validation#rule-unique

+5

BTW, löse ich das einen Platzhalter durch mit ': id:' in meinem Validierungsregeln und dann die Regeln vor der Validierung zu verarbeiten: https://github.com/betawax/role-model/blob/master/src/Betawax/RoleModel/RoleModel.php#L86-L101 –

+0

Ich mag die Idee, einen Platzhalter zu verwenden aber ich bin nicht wirklich überzeugt von Ihrer Herangehensweise. Irgendwelche Gedanken zu meiner "zweiten" Frage bezüglich eines Veränderungszustandes? Ich habe in der Quelle von Laravel 3 einige Referenzen über eine geänderte Methode gefunden, die ich aber noch nicht in Laravel gefunden habe. 4 –

+0

In meinem Codebeispiel ersetze ich den Platzhalter durch '$ this-> getKey()', was für neue * und * bestehende Datensätze. Sie müssen sich also nicht darum kümmern, ob Sie ein neues Modell erstellen oder ein vorhandenes Modell aktualisieren. Ersetzen Sie den Platzhalter bei jedem Speichervorgang. Sie können dies entweder tun, indem Sie die 'save()' - Methode von Eloquent überschreiben oder indem Sie [model events] (http://four.laravel.com/docs/eloquent#model-events) verwenden. –

1

finden Sie in der Dokumentation auf http://four.laravel.com/docs/validation#rule-unique

Sie eigene ID, um den Benutzer

ausschließen
protected $rules= [ 
    'name' => 'required', 
    'email' => [ 
     'required', 
     'unique:user,email,THE_USERS_USER_ID', 
     'email' 
    ] 
]; 
+1

Ich kenne den Parameter exclude, aber ich sehe keine gültige nicht-hackische Art, sie in meinen Regelsatz zu injizieren, daher die Frage. –

+0

Warum halten Sie dieses hackish? – Puzbie

0

Ich behandle diese Art der Sache in meiner Prüffunktion. Mein Validator-Array wird als Klassenvariable eingerichtet. Ich mache dann so etwas wie diese:

public function validate() 
{ 
    //exclude the current user id from 'unqiue' validators 
    if($this->id > 0) 
    { 
     $usernameUnique = 'unique:users,username,'.$this->id; 
     $emailUnique = 'unique:users,email,'.$this->id; 
     $apiUnique = 'unique:users,api_key,'.$this->id; 
    } 
    else 
    { 
     $usernameUnique = 'unique:users,username'; 
     $emailUnique = 'unique:users,email'; 
     $apiUnique = 'unique:users,api_key'; 
    } 

    $this->validators['username'] = array('required', 'max:32', $usernameUnique); 
    $this->validators['email'] = array('required', 'max:32', $emailUnique); 
    $this->validators['api_key'] = array('required', 'max:32', $apiUnique); 

    $val = Validator::make($this->attributes, $this->validators); 

    if ($val->fails()) 
    { 
     throw new ValidationException($val); 
    } 
} 
4

Einen Ansatz ist es, eine Validierungsfunktion im Modell zu erstellen und mit dem Controller in der Eingabe, Szenario und id vorbei nennen (zu ignorieren).

public function validate($input, $scenario, $id = null) 
{ 
    $rules = []; 

    switch($scenario) 
    { 
     case 'store': 
      $rules = [ 
       'name'  => 'required|min:5|unique:users', 
       'email' => 'required|email|unique:users', 
       'password' => 'required|min:4|confirmed' 
      ]; 
      break; 

     case 'update'; 
      $rules = [ 
       'name'  => 'required|min:5|unique:users' .',name,' . $id, 
       'email' => 'required|email|unique:users' .',email,' . $id, 
       'password' => 'min:4|confirmed' 
      ]; 
      break; 
    } 

    return Validator::make($input, $rules); 
} 

Dann in der Steuerung:

$input  = Input::all(); 
    $validation = $user->validate($input, 'update', $user->id); 

    if ($validation->fails()) 
    { 
     // Do stuff 
    } 
    else 
    { 
     // Validation passes 
     // Do other stuff 
    } 

Wie andere schon erwähnt, der dritte Parameter der einzigartigen Regel gibt eine ID zu ignorieren. Sie können weitere Fälle hinzufügen, z. B. "Anmelden", um die Validierungsfunktion wiederzuverwenden.

Alternativ, Jeffrey Way unter Tuts Premium has a great series of lessons in "What's New In Laravel 4", die ein paar andere Ansätze zur Handhabung der Validierung mit Diensten und Listener enthält.

+0

Hinzufügen der Validierungsregeln zum Modell scheint die richtige Lösung zu sein. Imho ist es schmutzig, den Parameter zum Speichern oder Aktualisieren jedes Mal hinzuzufügen. Dieser Beitrag folgt einer ähnlichen Lösung http://forums.laravel.io/viewtopic.php?id=12104 vielleicht hilft das jemandem. – simon

1

Ab 2014.01.14 können Sie sometimes Attribut verwenden, glaube ich Taylor fügte sie vor 2 Tagen zu Laravel 4,1

$v = Validator::make($data, array(
    'email' => 'sometimes|required|email', 
)); 

sometimes nur Eingabe validieren, wenn es vorhanden ist. Dies kann zu Ihrem genauen Szenario passen oder auch nicht, wenn Sie keinen Standardwert für die Einfügung haben.

http://laravel.com/docs/validation#conditionally-adding-rules

+0

danke für das Teilen !! – simon

0

Ich habe dies für die Aktualisierung durch unterschiedliche Regeln gelöst und erstellen auf Modelle, die so wie Benutzer, tun müssen.

Ich habe eine Modellklasse, die Eloquent erstreckt, wo ich die Validierung definieren, und dann alle untergeordneten Modelle, die das Modell erweitern können beide haben die Regeln $ und update_rules $ definiert. Wenn Sie nur $ -Regeln definieren, wird es sowohl zum Erstellen als auch zum Aktualisieren verwendet.

class Model extends Eloquent { 
    protected $errors; 
    protected static $rules = array();  
    protected $validator; 

    public function __construct(array $attributes = array(), Validator $validator = null) { 
     parent::__construct($attributes);  
     $this->validator = $validator ?: \App::make('validator'); 
    } 

    protected static function boot() { 
     parent::boot(); 

     # call validatie when createing 
     static::creating(function($model) { 
      return $model->validate(); 
     }); 

     # call validatie when updating with $is_update = true param 
     static::updating(function($model) { 
      return $model->validate(true); 
     }); 
    } 

    public function validate($is_update = false) { 
     # if we have $update_rules defined in the child model, and save is an update 
     if ($is_update and isset(static::$update_rules)) { 
      $v = $this->validator->make($this->attributes, static::$update_rules); 
     } 
     else { 
      $v = $this->validator->make($this->attributes, static::$rules); 
     } 

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

     $this->setErrors($v->messages()); 
     return false; 
    } 

    protected function setErrors($errors) { 
     $this->errors = $errors; 
    } 

    public function getErrors() { 
     return $this->errors; 
    } 

    public function hasErrors() { 
     return ! empty($this->errors); 
    } 
}