validate
property of your model. In version 1.2, there is an on
option that can be set on a specific rule that, when set, is either create or update. This allows you to define different rules depending on the type of action being performed. That, in combination with the required and allowEmpty properties, give you a fair amount of control over different validation rules.Despite that, I developed a slightly different approach that allows for different validation sets to be specified and to be cleanly separated from each other.
I override the
validates
method within a custom AppModel
(stored in /app/app_model.php). The validates
method is called when a save
call is made or it can be called manually. This custom method can perform in one of two ways:Method One: Action-specific Validation Sets
It'll first look to see if you have a validation set specified for the current controller action. For example, if you were in the edit action, it'd look for a property in the model calledvalidateEdit
. If it doesn't exist, it'll default back to using the normal validate
property.class User extends AppModel {
// performs normal validation
var $validate = array( ... );
// used in an edit action like /users/edit/1
var $validateEdit = array( ... );
// used in a forgotpassword action like /users/forgotpassword
var $validateForgotpassword = array( ... );
}
In that Forgot Password example, this would allow you to avoid performing your own checks for even basic calls and keep the logic tucked away in the Model.class UsersController extends AppController {
function forgotpassword() {
$this->User->set($this->data);
if ($this->User->validates()) {
// send email to reset password and show success message
}
}
}
The thing I like about this is that the error messaging is handled by the validation and the FormHelper
. (Although, a more noticable flash message near the top of the page is also helpful.)Method Two: Custom Validation Sets
Alternatively, you may wish to specify a validation set manually before calling save or validates on a model. To do this, just specify a validationSet property on the model right before your call. The property will be unset immediately afterwards allowing normal validation rules to be applied.Here's an alternate approach to the forgotten password example:
class User extends AppModel {
var $validateForgotpassword = array( ... );
}
class UsersController extends AppController {
function forgot() {
$this->User->set($this->data);
$this->User->validationSet = 'forgotpassword';
if ($this->User->validates()) {
// send email to reset password and show success message
}
}
}
The Code
Here is the custom validates method that pulls this all off:function validates($options = array()) {
// copy the data over from a custom var, otherwise
$actionSet = 'validate' . Inflector::camelize(Router::getParam('action'));
if (isset($this->validationSet)) {
$temp = $this->validate;
$param = 'validate' . $validationSet;
$this->validate = $this->{$param};
} elseif (isset($this->{$actionSet})) {
$temp = $this->validate;
$param = $actionSet;
$this->validate = $this->{$param};
}
$errors = $this->invalidFields($options);
// copy it back
if (isset($temp)) {
$this->validate = $temp;
unset($this->validationSet);
}
if (is_array($errors)) {
return count($errors) === 0;
}
return $errors;
}
Link de la fuente