2013-05-13 43 views
6

tôi sử dụng các quy tắc sau đây để xác nhận về việc tạo ra một người dùng mới:Laravel 4 Validation

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

Khi cập nhật một người dùng hiện tôi sử dụng ruleset giống như trình bày ở trên nhưng không muốn một lỗi xác nhận nếu người dùng đã không thay đổi email của mình cả.

Tôi hiện giải quyết điều này bằng cách sử dụng như sau:

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

Nó cảm thấy giống như một workaround bẩn với tôi vì vậy tôi đã tự hỏi nếu có những lựa chọn thay thế tốt hơn.

Cũng lưu ý rằng phương pháp changed là thứ tôi đã tự viết. Có ai biết nếu có là một phương pháp Laravel 4 bản địa để kiểm tra xem một thuộc tính mô hình có thay đổi không?

Cảm ơn!

+0

Hi kiểm tra câu trả lời này của tôi trong câu hỏi này [http://stackoverflow.com/questions/16976207/laravel-4-validation-uniquedatabase-ignore-current][1], tôi hy vọng sự giúp đỡ này. [1]: http://stackoverflow.com/questions/16976207/laravel-4-validation-uniquedatabase-ignore-current – Bradley

Trả lời

9

Quy tắc xác thực duy nhất cho phép bỏ qua ID đã cho, trong trường hợp của bạn là ID của tập dữ liệu bạn đang cập nhật.

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

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

+5

BTW, tôi giải quyết việc này bằng cách sử dụng một placeholder ': id:' trong tôi quy tắc xác thực và sau đó xử lý các quy tắc trước khi xác thực: https://github.com/betawax/role-model/blob/master/src/Betawax/RoleModel/RoleModel.php#L86-L101 –

+0

Tôi thích ý tưởng sử dụng trình giữ chỗ nhưng tôi không thực sự bị thuyết phục bởi cách tiếp cận của bạn. Bất kỳ suy nghĩ về câu hỏi 'thứ hai' của tôi liên quan đến một trạng thái thay đổi? Tôi tìm thấy một số tài liệu tham khảo trong nguồn Laravel 3 về một phương pháp thay đổi nhưng không tìm thấy nó cho đến nay trong Laravel 4 –

+0

Trong ví dụ mã của tôi, tôi thay thế trình giữ chỗ bằng '$ this-> getKey()' có sẵn cho * mới và * tập dữ liệu hiện có. Vì vậy, bạn không phải quan tâm đến việc bạn đang tạo mới hay cập nhật một mô hình hiện có. Chỉ cần thay thế trình giữ chỗ trên mọi sự kiện lưu. Bạn có thể làm điều này bằng cách ghi đè phương thức 'save()' của Eloquent hoặc bằng cách sử dụng [sự kiện mô hình] (http://four.laravel.com/docs/eloquent#model-events). –

1

Xem tài liệu trên http://four.laravel.com/docs/validation#rule-unique

Bạn có thể loại trừ những người sử dụng id riêng

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

Tôi biết về các tham số loại trừ nhưng tôi thấy không có cách nào không hackish cách tiêm nó vào ruleset của tôi do đó câu hỏi. –

+0

Tại sao bạn lại xem xét vụ tấn công này? – Puzbie

0

tôi xử lý các loại điều này trong chức năng validator của tôi. Mảng xác nhận hợp lệ của tôi được thiết lập dưới dạng biến lớp. Sau đó tôi làm một cái gì đó như thế này:

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

Một cách tiếp cận là tạo một hàm xác nhận trong mô hình và gọi nó với bộ điều khiển truyền vào đầu vào, kịch bản và id (bỏ qua).

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

Sau đó, trong bộ điều khiển:

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

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

Như những người khác đã đề cập, tham số thứ 3 của sự cai trị độc đáo chỉ một id để bỏ qua. Bạn có thể thêm các trường hợp khác, chẳng hạn như 'đăng nhập' để sử dụng lại chức năng xác thực.

Hoặc, Jeffrey Way tại Tuts Premium has a great series of lessons in "What's New In Laravel 4" bao gồm một số phương pháp tiếp cận khác để xử lý xác thực bằng cách sử dụng dịch vụ và người nghe.

+0

thêm các quy tắc xác thực vào mô hình có vẻ là giải pháp phù hợp. imho nó bẩn để thêm các tham số cho cửa hàng hoặc cập nhật mọi lúc. bài đăng này sau một giải pháp tương tự http://forums.laravel.io/viewtopic.php?id=12104 có thể điều này giúp một người nào đó. – simon

1

Tính đến 2014/01/14, bạn có thể sử dụng thuộc tính sometimes, tôi tin rằng Taylor thêm họ 2 ngày trước để Laravel 4,1

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

sometimes chỉ xác nhận đầu vào nếu nó tồn tại. điều này có thể hoặc không phù hợp với kịch bản chính xác của bạn, nếu bạn không có giá trị mặc định để chèn.

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

+0

cảm ơn bạn đã chia sẻ điều này !! – simon

0

tôi đã giải quyết điều này bằng cách quy tắc khác nhau để cập nhật và tạo trên các mô hình mà cần phải làm như vậy, như người dùng.

Tôi có một lớp mẫu mà kéo dài hùng hồn, nơi tôi xác định xác nhận, và sau đó tất cả các mẫu con mà mở rộng mô hình có thể có có cả $ quy tắc$ update_rules xác định. Nếu bạn xác định chỉ có $ quy tắc, nó sẽ được sử dụng cả hai để tạo và cập nhật.

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