Validation of optional fields with multiple validation rules

Published on and tagged with cakephp  model  validation

Recently, I encountered an issue while trying to validate an optional field for which I defined multiple validation rules. It’s one of those issues I call a bug whereas for the core developers it is a feature…

Let’s say we have an optional “nickname” field. Its value must either be empty or an alphanumeric string with a length between three and ten characters. We start with defining the validation rules:

public $validate = array('nickname' => array('length' => array('rule' => array('between', 3, 10)), 
		                             'alpha' => array('rule' => array('alphaNumeric'))));

Those rules work fine. The only “problem” is that they reject an empty string as invalid. To allow an empty string we have to set the option “allowEmpty” to true. So the $validate array is now:

public $validate = array('nickname' => array('length' => array('rule' => array('between', 3, 10)), 
		                             'alpha' => array('rule' => array('alphaNumeric')),
				             'allowEmpty' => true));

It looks correct, but as you might guess, it doesn’t work. An empty string still doesn’t pass the validation.

The problem is that “allowEmpty” has to be set on the first rule and not as a setting for the field. And so we have to change the $validate array to:

public $validate = array('nickname' => array('length' => array('rule' => array('between', 3, 10), 'allowEmpty' => true), 
		                             'alpha' => array('rule' => array('alphaNumeric'))));

With this solution, an empty string is accepted as a valid value. It’s not really logical, but it works ;-)

11 comments baked

  • walkerhamilton

    Hmmm…that’s odd. It worked just fine for me as a setting on the field…

    (I’m using 1.2.0.6311)

    But….I wasn’t even aware of the allowEmpty setting. This is awesome! I was always annoyed that something had to be completed and validated or not validated at all if I wanted it to be optional….this ends that war within my brain where those cases are concerned.

  • Terr

    Thanks for the heads-up, I’m sure this would be a maddening problem I’d run in some day.

    I don’t find it too illogical though. There has to be some sort of order in which the validation is done. From first to last rule sounds fine to me.

  • nate

    The original validation system was designed around only one rule per field, and when we went to multiple, the break-down of options followed suit. While not perfectly logical I could see this enabling certain complex conditional validations.

  • Tarique Sani

    Why bother – just use a regex :p

  • Peter Butler

    Many thanks, have had this problem mysel in the past and now know the most elegant of dealing with it in future builds

  • dr. Hannibal Lecter

    So that’s why it didn’t work for me.. :-)

    Thanks for the tip!

  • cakebaker

    @all: Thanks for your comments!

    @Walker: Maybe it has changed in the meantime, at least here with 1.2.0.7043 it doesn’t work with setting it on the field.

    @nate: Hm, I don’t see how this would enable complex conditional validations.

    @Tarique: If possible, I try to avoid regular expressions ;-)

  • Hulsy

    Hope you still read comments on old posts…
    I have the same problem with only one rule (‘alphaNumeric’) and ‘allowEmpty’. When the fields is left blank, the validation fails…
    Any idea ?

  • cakebaker

    @Hulsy: Hm, without code it is difficult to say why it fails. I tested it with the following code, and it worked fine with CakePHP 1.3.6:

    class Post extends AppModel {
        public $validate = array('title' => array('rule' => 'alphaNumeric', 'allowEmpty' => true));
    }
  • Hulsy

    Thanks for the reply. I fixed it.
    It was really stupid : I put quotes around true !!

  • cakebaker

    @Hulsy: Good to hear you could fix your issue :)

Bake a comment




(for code please use <code>...</code> [no escaping necessary])

© daniel hofstetter. Licensed under a Creative Commons License