I have a model Interesttype where i want two fields to be validated one should not be more than the other and none should be less than a particular set value. Here is my model.
class Interesttype extends AppModel
{
public $primaryKey = 'int_id';
public $displayField = 'int_name';
public $hasMany= array(
'Loan' => array(
'className' => 'Loan',
'foreignKey' => 'lon_int_id'
)
);
public $validate = array(
'int_name'=> array(
'rule' => 'notEmpty',
'allowEmpty' => false,
'message' => 'The interest type name is required.'
),
'int_active'=>array(
'rule'=>array('boolean'),
'allowEmpty'=>false,
'message'=>'Please select the status of this interest type'
),
'int_max'=> array(
'numeric'=>array(
'rule' => 'numeric',
'allowEmpty' => false,
'message' => 'Please specify a valid maximum interest rate.'
),
'comparison'=>array(
'rule' => array('comparison','>',1000),
'allowEmpty' => false,
'message' => 'The Maximum interest rate cannot be less than the special rate.'
),
'checklimits'=>array(
'rule' => array('checkRateLimits','int_min'),
'allowEmpty' => false,
'message' => 'The Maximum interest rate cannot be less than the minimum rate.'
)
),
'int_min'=> array(
'numeric'=>array(
'rule' => 'numeric',
'allowEmpty' => false,
'message' => 'Please specify a valid minimum interest rate.'
),
'comparison'=>array(
'rule' => array('comparison','>',1000),
'allowEmpty' => false,
'message' => 'The Minimum interest rate cannot be less than the special rate.'
))
);
function checkRateLimits($maxr,$minr){
if($maxr>=$minr){
return true;
}
else{
return false;
}
}
}
the above model validates my forms well except that one check will not be done, it will not check if the maximum interest rate is indeed more than or equal to the minimum inerest rate. Where am i going wrong on the validation?
I don't think you can achieve this with directly inserting it into the validate array in a model. You can however specify your own validation function. An example is given here (look at the model code):
In your Model your validate should be field name with rule pointing to the function you want to run.
And "None should be less than a particular set value" I would use the "range" validation as seen below. The example will accept any value which is larger than 0 (e.g., 1) and less than 10
public $validate = array(
'maxr'=>array(
'Rate Limits'=>array(
'rule'=>'checkRateLimits',
'message'=>'Your Error Message'
),
'Greater Than'=>array(
'rule'=>array('range', -1, 11),
'message'=>'Please enter a number between 0 and 10'
)
),
);
In the function you pass $data which is the fields being passed. If $data doesn't work try $this->data['Model']['field'] ex($this->data['Model']['maxr'] >= $this->data['Model']['minr'])
function checkRateLimits($data){
if ( $data['maxr'] >= $data['minr'] ) {
return true;
} else {
$this->invalidate('minr', 'Your error message here');
return false;
}
}
Your Form would be something like
echo $this->Form->create('Model');
echo $this->Form->input('maxr');
echo $this->Form->input('minr');
echo $this->Form->end('Submit');
I won't help you to do your code however I will suggest you to read the following backery article http://bakery.cakephp.org/articles/aranworld/2008/01/14/using-equalto-validation-to-compare-two-form-fields
<?php
class Contact extends AppModel
{
var $name = 'Contact';
var $validate = array(
'email' => array(
'identicalFieldValues' => array(
'rule' => array('identicalFieldValues', 'confirm_email' ),
'message' => 'Please re-enter your password twice so that the values match'
)
)
);
function identicalFieldValues( $field=array(), $compare_field=null )
{
foreach( $field as $key => $value ){
$v1 = $value;
$v2 = $this->data[$this->name][ $compare_field ];
if($v1 !== $v2) {
return FALSE;
} else {
continue;
}
}
return TRUE;
}
}
?>
modify the code I think it should be easy from here.
You'll have to add your own Validation Method to make this possible. Here's a pretty generic example that makes use of Validation::comparison()
and supports all of its operators (>
, <
, >=
, <=
, ==
, !=
, isgreater
, isless
, greaterorequal
, lessorequal
, equalto
, notequal
) as the second argument in the options array and a field name to compare the validated value to as a third parameter.
class MyModel extends AppModel
{
/* Example usage of custom validation function */
public $validate = array(
'myfield' => array(
'lessThanMyOtherField' => array(
'rule' => array('comparisonWithField', '<', 'myotherfield'),
'message' => 'Myfield value has to be lower then Myotherfield value.',
),
),
);
/* Custom validation function */
public function comparisonWithField($validationFields = array(), $operator = null, $compareFieldName = '') {
if (!isset($this->data[$this->name][$compareFieldName])) {
throw new CakeException(sprintf(__('Can\'t compare to the non-existing field "%s" of model %s.'), $compareFieldName, $this->name));
}
$compareTo = $this->data[$this->name][$compareFieldName];
foreach ($validationFields as $key => $value) {
if (!Validation::comparison($value, $operator, $compareTo)) {
return false;
}
}
return true;
}
}
This is generic, so you could throw the function in your AppModel
if you want to make use of it in multiple models in your App. You could also make this a Behavior to share it between different models.