1
votes

Say I have a fairly typical, by-the-docs validation array and I want to keep those rules and add a specific validation rule for 8+ other fields.

Original $validate:

var $validate = array( 
    'name' => array( 
        'notEmpty'=> array( 
            'rule' => 'notEmpty', 
            'message' => 'Name can not be blank.' 
        ), 
        'allowedCharacters'=> array( 
            'rule' => '|^[a-zA-Z ]*$|', 
            'message' => 'Name can only be letters.' 
        ), 
        'minLength'=> array( 
            'rule' => array('minLength', 3), 
            'message' => 'Name must be at least 3 characters long.' 
        ), 
        'maxLength'=> array( 
            'rule' => array('maxLength', 255), 
            'message' => 'Name can not be longer that 255 characters.' 
        ) 
    ), 
    'email' => array( 
        'email' => array( 
            'rule' => 'email', 
            'message' => 'Please provide a valid email address.' 
        ), 
        'isUnique' => array( 
            'rule' => 'isUnique', 
            'message' => 'This E-mail used by another user.' 
        ) 
    )         
); 

I can add the following rule to the validation array, but I do not want to have to repeat it 8 times.

 ////fragment of array
    'field1' => array(
        'greaterThanField' => array(
            'rule' => array('greaterThanField', 'age'),
            'message' => 'This field cannot be greater than age'
        )
    )
////

 function greaterThanField( $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; 
} 

And I want to add to this an array of field names that will all be evaluated using the same rule and message. I tried creating a variable in the model and then running code on the beforeValidate function, but beforeValidate doesn't seem to have access to the compareFields variable

var $compareFields = array('field1', 'field2', 'field3', 'field4', 'field5', 'field6', 'field7', 'field8');

function beforeValidate(){
    foreach ($compareFields as $field) {
        $validate[$field] = array(
            'rule'=> array('greaterThanField', 'age' ),
            'message'=>'Cannot exceed delivery age',
        );
    }
}

What is the proper way to achieve this?

1
Typically beforeValidate or __construct are used for this purpose - as such the answer-in-the-question is fine. Note though you're overwriting all validation rules for field $field, better to write as $validate[$field]['greaterThanField'] =, so that if you add other rules later you don't wipe them out with this logic. - AD7six
I changed it from $compareFields to $this->compareFields and it started working. - Damon
it wasn't clear from the question - that your code wasn't working :) - AD7six

1 Answers

0
votes

If you're using 2.2 then check this.

If you're using an older version and (if I understood correctly your question) you are too lazy to add the same validation rule to multiple fields, then I would add them dynamically in the constructor of your model. I don't like that solution though, I would stick to the convention.