2014-01-17 89 views
2

我希望能夠在啓動保存之前驗證創建相關模型的表單。我正在拯救一個擁有多個相關模型的組織。由於我有許多多對多關係,所以我必須先創建主模型,然後再從輸入數據中分別創建每個相關模型。在創建初始組織後,我在組織資源庫中調用'createRelated'方法。Laravel 4中相關模型驗證的最佳實踐?

public function createRelated($input) 
{ 
    $this->orgtypes()->attach(1, ['objectstate_id' => ORGANIZATION_STARTED]); 
    $this->addresses()->create(array_only($input, ['street1', 'zip', 'city', 'state_code'])); 
    for ($i=0; $i < 2; $i++) 
    { 
     if($input['phone_numbers_'.$i.'_number']) 
     { 
      $this->phoneNumbers()->create(['phone_number_type_id' => $input['phone_numbers_'.$i.'_phone_number_type_id'], 'number' => $input['phone_numbers_'.$i.'_number']]); 
     } 
    } 
    $this->procedures()->attach($input['procedures']);  
    $input['objectstate_id'] = USER_STARTED; 
    $input['password'] = $this->encryptPassword($input['password']); 
    $this->users()->create(array_only($input, ['first_name', 'last_name', 'email', 'password', 'objectstate_id'])); 
    $this->profileElements()->create(['type' => 'short_description', 'content' => $input['short_description']]); 
} 

有叫出每個輸入並將其發送到其相應的模型似乎並沒有我的權利,但是這是我聽到的IRC爲「正確」的方式。但是現在我來驗證一下,即使輸入可能違反驗證規則,目前也沒有驗證這些模型的創建。我很驚訝沒有命名約定(我已經看到)清楚地標識了相關的模型輸入,因此它可以全部驗證和創建,而無需像上面那樣進行手動處理。在開始上述保存事務之前,如何驗證相關輸入數據的任何想法?

我對組織驗證的樣子:

<?php namespace Acme\Validators\Organizations; 

use Acme\Validators\ValidatorAbstract; 

class Validator extends ValidatorAbstract { 

    /** 
    * Validation rules 
    */ 
    protected $rules = array(
     'organization_name' => 'required' 
    ); 

    /** 
    * Custom Validation Messages 
    */ 
    protected $messages = array(
    ); 

} 

<?php namespace Acme\Validators; 

use Illuminate\Support\MessageBag as MessageBag; 


/* 
* This class defines abstract Validator methods 
*/ 

abstract class ValidatorAbstract implements ValidatorInterface { 
    protected $validator; 

    protected $input; 

    protected $errors; 

    /** 
    * @param array $input 
    * 
    */ 
    public function __construct($input = NULL, MessageBag $bag) 
    { 
     $this->input = $input ?: \Input::all(); 

     $this->validator = \Validator::make($this->input, $this->rules, $this->messages); 
     $this->errors = $bag; 
    } 

    /** 
    * Run validation on input. 
    * 
    * @return boolean 
    */ 
    public function passes() 
    { 
     if($this->validator->passes()) 
     { 
      return true; 
     } 
     $this->errors = $this->validator->messages(); 

     return false; 
    } 

    /** 
    * Get all errors stored. 
    * 
    * @return MessageBag 
    */ 
    public function getErrors() 
    { 
     return $this->errors; 
    } 

    /** 
    * Add new error. 
    * 
    * @return MessageBag 
    */ 
    public function addError($key, $message) 
    { 
     return $this->errors->add($key, $message); 
    } 

} 

我的抽象庫類,我在熾熱

<?php namespace Acme\Repositories; 

// use Eloquent; 
use LaravelBook\Ardent\Ardent; 

/* 
* This class defines Eloquent methods 
*/ 

abstract class EloquentRepositoryAbstract extends Ardent implements RepositoryInterface { 

    protected $guarded = []; 

    public $timestamps = false; 
    public $autoHydrateEntityFromInput = true; // Ardent hydrates on new entries' validation 
    public $forceEntityHydrationFromInput = true; // Ardent hydrates whenever validation is called 
… 

我控制器帶來:

<?php 

use \Acme\Repositories\Organizations\OrganizationRepositoryInterface; 
use \Acme\Validators\Organizations\Validator; 
use \Acme\Validators\Users\EditValidator as UsersValidator; 

class OrganizationsController extends BaseController { 

    /** 
    * Organization Repository 
    * 
    * @var repository 
    * @var validator 
    * @var usersValidator 
    */ 
    protected $repository; 
    protected $validator; 
    protected $usersValidator; 

    public function __construct(OrganizationRepositoryInterface $repository, 
           Validator $validator, 
           UsersValidator $usersValidator) 
    { 
     $this->repository = $repository; 
     $this->validator = $validator; 
     $this->users_validator = $usersValidator; 
    } 

[...]香草雄辯的風格店鋪方式:

public function store() 
    { 
     $input = Input::all(); 
     $opasses = $this->validator->passes(); 
     $ppasses = $this->repository->validateProcedure($input); 
     $upasses = $this->users_validator->passes(); 
     if($opasses && $ppasses['status'] && $upasses) 
     { 
      $new_organization = $this->repository->create(['organization_name' => $input['organization_name']]); 
      if($input['logo_url']) 
      { 
       $new_organization->processImage($input, Request::root());    
      } 
      if($new_organization->saveRelated($input, 'create')) 
      { 
       return Redirect::route('home') 
        ->with('message', 'Organization Created.');    
      } 
      else 
      { 
       return Redirect::route('organizations.create') 
        ->withInput() 
        ->with('message', 'There were errors in the creation of this Organization');    
      } 
     } 
     return Redirect::route('organizations.create') 
      ->withInput() 
      ->withErrors(array_merge($this->validator->getErrors()->toArray(), $this->users_validator->getErrors()->toArray(), $ppasses)) 
      ->with('message', 'There were validation errors.'); 

    } 

這一切似乎過於複雜和脆弱。

回答

0

我認爲最棘手的決定是在調用驗證方法之前放置驗證規則的地方。這裏有一個鏈接,將有助於:http://laravel.com/docs/validation#available-validation-rules

下面是我做了我的,但我仍然決定在哪裏放置驗證規則/錯誤消息。

Laravel 4內置的驗證類有一個方法,使得驗證真正的輕鬆:

Validator::make($input, $rules=array(), $errors=array()) 

(第三個參數是可選的)

在你的情況,你打電話給你創建的方法(假設這是前用來保存元素),你可以這樣做:

$rules = array(
    "first_name" : "required", 
    "second_name" : "required", 
    and so on... 
); 

我給的鏈接,你會給你的可能的規則。最後,您還可以創建自己的自定義錯誤消息,如下所示:

$messages = array(
    "required" => "This :attribute field is required" 
    and so on... 
); 

::屬性將填寫自動驗證失敗的字段。

然後,驗證您剛剛通過這些陣列和調用通行證()方法或失敗()方法:

Validator::make($input, $rules, $messages)->passes() (如果通過返回true,false,如果失敗) 它看起來更乾淨我認爲做這樣:

$validation = Validator::make($input, $rules, $messages); 
if ($validation->passes()) { 
     // save data 
} 

作爲獎勵,你可以從這個數組訪問錯誤信息:

$errors = $validation->messages(); 

所以,我希望能回答你的問題。我認爲最大的問題是在哪裏放置這些驗證規則,因爲我認爲還沒有一個約定。如果您有任何問題,請分享您的見解和意見。謝謝。

+0

那麼我現在有我認爲一個不好的解決方案。我正在使用存儲庫模式和驗證作爲服務。 – user3061986

+0

是的,我認爲這與你原來的帖子完全不同,因爲你現在問的是應用程序架構而不是如何驗證輸入。 –