2015-06-27 2 views
7

Несколько вопросов о проверке, которые могут быть вместе, потому что они все вроде адресация новую концепцию проверки в CakePHP 3.Смешение Validation против правил применения в CakePHP3

Я прочитал главы (1, 2, 3) в кулинарной книге несколько раз, но, честно говоря, я не понимаю, как это сделать правильно. Я также знаю, что в настоящее время существует issue/discussion at GitHub о валидации в CakePHP3, которая может адресовать ту же тему.

Ошибки проверки инициируются, например. с patchEntity. Так что я думаю, что лучше всегда проверять/ошибку отображения перед выполнением сохранения действия:

// src/Controller/UsersController.php 
public function add() { 
    $user = $this->Users->newEntity(); 
    if ($this->request->is('post')) { 
    $user = $this->Users->patchEntity($user, $this->request->data, ['validate' => 'default']); 
    if ($user->errors()) { 
     $this->Flash->error('There was a Entity validation error.'); 
    } else { 
     // Optional: Manipulate Entity here, e.g. add some automatic values 
     // Be aware: Entity content will not be validated again by default 
     if ($this->Users->save($user)) { 
     $this->Flash->succeed('Saved successfully.'); 
     return $this->redirect(['controller' => 'Users', 'action' => 'index']); 
     } else { 
     $this->Flash->error('Not saved - ApplicationRule validation error.'); 
     } 
    } 
    } 
    $this->set('user', $user); 
} 

Почему поваренная книга учебников не использовать $user->errors() перед сохранением данных? Насколько я понимаю, save не нужно вызывать, если уже была ошибка проверки! Другим способом было бы объединить проверку ошибок и сохранить действие:

if (!$user->errors() && $this->Users->save($user)) { 
    $this->Flash->succeed('Saved successfully.'); 
    return $this->redirect(['controller' => 'Users', 'action' => 'index']); 
} else { 
    $this->Flash->error('There was a validation OR ApplicationRule error.'); 
} 

Вы используете это? Должен ли я использовать его? Или если нет, почему бы и нет?

Почему CakePHP показывает ошибки проверки, даже если я НЕ использую $user->errors() в контроллере, как во всех примерах поваренной книги? Я думал, что save НЕ проверит проверку объекта ?!

Пример: isUnique

Согласно cookbook «Обеспечение электронной единственность» является примером использования правил применения.

// src/Model/Table/UsersTable.php 
namespace App\Model\Table; 
use Cake\ORM\Table; 
use Cake\ORM\RulesChecker; 
use Cake\ORM\Rule\IsUnique; 
// Application Rules 
public function buildRules(RulesChecker $rules) { 
    $rules->add($rules->isUnique(['email'], 'This email is already in use')); 
    return $rules; 
} 

Ошибка будет срабатывать только с save -Call в контроллере. Но также можно проверить уникальность в проверке. Почему лучше НЕ делать это таким образом?

// src/Model/Table/UserTable.php 
namespace App\Model\Table; 
use Cake\ORM\Table; 
use Cake\Validation\Validator; 
public function validationDefault(Validator $validator) { 
    $validator 
    ->add('email', [ 
     'unique' => [ 
     'rule' => 'validateUnique', 
     'provider' => 'table', 
     'message' => 'This email is already in use' 
     ], 
     ]) 
    return $validator; 
} 

Если я могу добавить ApplicationRule в Validation, зачем вообще использовать ApplicationRules?

Как я могу определить в ApplicationRule КОГДА правило должно применяться только в конкретном действии (не все вызовы создания/обновления)?

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

В случае, если я автоматически добавлю значения к объекту, я хочу быть уверенным, что все значения сохраняются до сохранения их в базе данных (как в CakePHP2). Поэтому я бы предположил, что лучше/неудобно ALWAYSUsing Validation as Application Rules?!

Как вы имеете дело с этим в целом? Существуют ли другие примеры для демонстрации/демонстрации преимуществ и некоторых вариантов использования Validation vs. ApplicationRules?

ответ

6

Я думаю, что основным источником недоразумений является то, что вы не знаете, что save() не сохранит объект, если он содержит ошибки.Например:

$entity = $users->newEntity(['email' => 'not an email']); 
$users->save($entity); // Returns false 

Причина, по которой будет возвращать ложь, потому что save() читает $entity->errors() результат перед выполнением фактического процесса сохранения. Поэтому нет необходимости проверять ошибки вручную, прежде чем звонить save(), так же, как показывают примеры в руководстве.

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

Важно помнить, что Validation, как и в методах validation*(), предназначен для предоставления людям обратной связи с данными, которые они предоставляют. Перед тем, как начнется процесс сохранения, вы хотите представить все ошибки в форме (включая ошибки для вложенных свойств).

С Validation редко происходит внутри транзакции базы данных, нет фактической гарантии, что между валидацией и сохранением электронной почты все равно будет уникальным. Это одна из тех задач, которые пытается решить приложение: правила приложения выполняются в той же транзакции, что и остальная часть процесса сохранения, поэтому любые проверки donde там будут иметь гарантию согласованности.

Еще одна проблема заключается в том, что они могут работать с данными, которые уже установлены на объекте, поэтому у вас есть полный доступ к текущему состоянию объекта. Это невозможно при исправлении объекта или при создании нового, поскольку любые переданные данные потенциально непоследовательны.

+0

Так, чтобы избежать сюрпризов при сохранении данных, это лучший способ всегда использовать валидацию также в качестве правил приложения? Я думаю, что это единственный способ убедиться, что данные все еще действительны, если сущность манипулирует между созданием и сохранением объекта? Можете ли вы привести некоторые конкретные примеры, когда правила приложения абсолютно лучше, чем проверки (нет кода, просто используйте случаи, когда есть большое преимущество)? Потому что я думаю, что с [условная проверка] (http://book.cakephp.org/3.0/en/core-libraries/validation.html#conditional-validation) я могу сделать в основном то же самое, что и с правилами приложения –

+0

Существует [пример с бесплатной доставкой в ​​качестве правила приложения] (http://book.cakephp.org/3.0/en/orm/validation.html#validation-vs-application-rules). Я мог бы также сделать это с условной проверкой 'return $ context ['data'] ['price'] <100 && $ context ['data'] ['shipping_mode'] === 'free';' –

+1

Я уже дал пример в моем ответе: правила приложения выполняются в транзакции, поэтому они являются единственным способом обеспечить постоянство данных. Специально для правил, которые включают вычисления. –

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