2014-01-17 2 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); 
    } 

} 

Мой абстрактный класс Repository, где я приношу в ретивого

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

[...] Vanilla красноречивый стиль магазин способ:

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

The: атрибут заполнит поле, которое не прошло проверку автоматически.

Затем, чтобы проверить вы просто передать в этих массивах и вызвать пропуски() метод или не удается() метод:

Validator::make($input, $rules, $messages)->passes() (возвращает истину, если он будет принят, ложь, если не удалось) Это будет выглядеть чище в мое мнение, чтобы сделать это таким образом:

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

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

$errors = $validation->messages(); 

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

+0

Ну, в настоящее время у меня есть то, что я считаю плохим решением. Я использую шаблон репозитория и проверки как службу. – user3061986

+0

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

Смежные вопросы