2013-05-13 2 views
6

Я использую следующие правила для проверки на создание нового пользователя:Laravel 4 Проверка

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

При обновлении существующего пользователя я использую один и тот же набор правил, как показано выше , но не хотите, ошибка проверки, если пользователь не изменил свою электронную почту вообще.

я в настоящее время решить эту проблему с помощью следующих действий:

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

Он чувствует, как грязные обходной путь для меня, так мне было интересно, если есть лучшие альтернативы.

Также обратите внимание, что метод changed - это то, что я написал сам. Кто-нибудь знает, существует ли - родной метод Laravel 4 для проверки того, изменилось ли свойство модели?

Спасибо!

+0

Привет проверить это мой ответ на этот вопрос [http://stackoverflow.com/questions/16976207/laravel-4-validation-uniquedatabase-ignore-current][1], я надеюсь, что это поможет. [1]: http://stackoverflow.com/questions/16976207/laravel-4-validation-uniquedatabase-ignore-current – Bradley

ответ

9

Уникальное правило проверки позволяет игнорировать данный идентификатор, который в вашем случае является идентификатором набора данных, который вы обновляете.

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

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

+5

BTW, я решить эту проблему, используя заполнитель ': ID:' в моем правила проверки, а затем обработать правила до проверки: https://github.com/betawax/role-model/blob/master/src/Betawax/RoleModel/RoleModel.php#L86-L101 –

+0

Мне нравится идея использования заполнитель но я не уверен в вашем подходе. Любые мысли по моему «второму» вопросу об изменении состояния? Я нашел некоторые ссылки в источнике Laravel 3 об измененном методе, но пока не нашел его в Laravel 4 –

+0

В моем примере кода я заменяю placeholder '$ this-> getKey()', который доступен для новых * и * существующие наборы данных. Поэтому вам не нужно заботиться о том, создаете ли вы новую или обновляете существующую модель. Просто замените местозаполнитель на каждое событие сохранения. Вы можете сделать это, перезаписав метод «Сохранить()» Eloquent или используя [образцовые события] (http://four.laravel.com/docs/eloquent#model-events). –

1

Смотрите документацию по http://four.laravel.com/docs/validation#rule-unique

Вы можете исключить пользователей, собственный идентификатор

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

Я знаю об исключающем параметре, но я не вижу действительного не-хакерского способа впрыскивания его в свой набор правил, следовательно, вопрос. –

+0

Почему вы считаете это хакерским? – Puzbie

0

Я обрабатывать такого рода вещи в моей функции валидатор. Мой массив валидаторов настроен как переменная класса. то я что-то вроде этого:

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

Один подход заключается в создании функции проверки в модели и вызвать его с помощью контроллера, проходящего на входе, сценарии и ид (игнорировать).

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); 
} 

Тогда в контроллере:

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

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

Как уже упоминалось других, третий параметр уникального правило определяет идентификатор, чтобы игнорировать. Вы можете добавить другие случаи, такие как «login», чтобы повторно использовать функцию проверки.

В качестве альтернативы, Джеффри Уэй в Tuts Premium has a great series of lessons in "What's New In Laravel 4", который включает в себя несколько других подходов к обработке валидации с использованием служб и слушателей.

+0

добавление правил проверки в модель представляется правильным решением. imho грязно добавлять параметр для хранения или обновления каждый раз. этот пост следует аналогичному решению http://forums.laravel.io/viewtopic.php?id=12104, возможно, это помогает кому-то. – simon

1

По состоянию на 2014-01-14, вы можете использовать атрибут sometimes, я считаю, Тейлор добавил их 2 дня назад Laravel 4.1

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

sometimes только проверить ввод, если он существует. это может или не подходит для вашего точного сценария, если у вас нет значения по умолчанию для вставки.

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

+0

спасибо, что поделились этим! – simon

0

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

У меня есть класс Model, который расширяет красноречив, где я определяю проверку, а затем все дочерние модели, расширяющие модель может иметь иметь как $ правила и $ update_rules определены. Если вы определяете только $ rules, он будет использоваться как для создания, так и для обновления.

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); 
    } 
}