我已多次阅读食谱中的章节(1,2,3)但老实说,我不明白如何以正确的方式做到这一点.我也知道目前有一个关于CakePHP3中的验证的issue/discussion at GitHub可能涉及相同的主题.
验证错误被触发,例如与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; }
只有控制器中的保存调用才会触发错误.但也可以检查验证中的唯一性.为什么不这样做更好?
// 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,为什么我应该/应该使用ApplicationRules?
如何在ApplicationRule中定义规则应仅应用于特定操作(并非所有创建/更新调用)?
在patchEntity-call之后操作实体时,我也没有看到或理解两个分离的验证状态的好处.
如果我自动向实体添加一些值,我想确保在将它们保存到数据库之前值仍然有效(如在CakePHP2中).所以我猜它总是更好/ nessecary总是Using Validation as Application Rules ?!
你如何处理这个问题?是否有其他示例可用于显示/演示Validation与ApplicationRules的好处和一些用例?
$entity = $users->newEntity(['email' => 'not an email']); $users->save($entity); // Returns false
它将返回false的原因是因为save()在继续实际保存过程之前读取$entity-> errors()结果.因此,在调用save()之前,不需要手动检查错误,就像手册中的示例所示.
电子邮件唯一性示例有点棘手,因为您要检查面向用户的表单(目标验证)和应用程序规则.
重要的是要记住验证,如验证*()方法,用于向人们提供有关他们提供的数据的反馈.您希望在保存过程开始之前在表单中显示所有错误(包括嵌套属性的错误).
由于验证很少发生在数据库事务中,因此在验证和保存电子邮件之间没有实际保证仍然是唯一的.这是应用程序规则试图解决的问题之一:应用程序规则在与保存过程的其余部分相同的事务中运行,因此任何支持都会有一致性保证.
应用程序规则解决的另一个问题是它们可以处理已在实体上设置的数据,因此您可以完全访问对象的当前状态.在修补实体或创建新实体时,这是不可能的,因为任何传递的数据都可能不一致.