Multiple questions about validation which may belong together, because they are all kind of adressing the new validation concept in CakePHP 3.
I have read the chapters (1, 2, 3) in the cookbook multiple times but honestly I don't understand how to do it the right way. I also know there is currently a issue/discussion at GitHub about the Validation in CakePHP3 which may address the same topic.
Validation errors are triggered e.g. with patchEntity. So I would think it is better to ALWAYS check/display errors BEFORE doing the save action:
// 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);
}
Why do the cookbook tutorials not make use of $user->errors()
before saving data? As far as I understand it save
doesn't need to be called if there was a validation error already?! Another way would be to combine the error-check and save action:
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.');
}
Are you using this? Should I use it? Or if not, why not?
Why is CakePHP showing the validation errors even if I do NOT use $user->errors()
in the controller, like in all the cookbook examples? I thought save
will NOT check the entity validation?!
Example: isUnique
According to the cookbook "Ensuring email uniqueness" is a use case for application rules.
// 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;
}
The error would only be triggered with a save
-call in the controller. But it is also possible to check uniqueness in the validation. Why is it better to NOT do it this way?
// 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;
}
If I can add the ApplicationRule in the Validation, why would/should I use ApplicationRules at all?
How can I define in the ApplicationRule WHEN the Rule should be applied only in a specific action (not all create/update calls)?
I also don't see or understand the benefit of the two separated validation states when the entity is manipulated after the patchEntity
-call.
In case I add some values automatically to the entity, I want to be sure that the values are all still valid before saving them to the database (as in CakePHP2). So I would guess it's better/nessecary to ALWAYS Using Validation as Application Rules?!
How are you dealing with this in general? Are there other examples available to show/demonstrate the benefit and some use cases of the Validation vs. ApplicationRules?