merging rules() in child from parent Class

Hi,

I’m new to this forum and have my first “problem” and I don’t know if it is a bug or if I think/code wrong so here is my simple example:




// ClassA => generated gii model code

class ClassA extends CActiveRecord {

  public static function model($className=__CLASS__) {

    return parent::model($className);

  }


  public function tableName() {

    return '{{classa}}';

  }


  public function rules() {

    return array(

      array('username', 'length', 'max'=>20), // generated rule cause of varchar(20) db field

    );

  }

}




// ClassB => used for my "method's"

class ClassB extends ClassA {

  public function rules() {

    $rules=parent::rules();

    return CMap::mergeArray($rules,array(

      array('username', 'length', 'min'=>10),

    ));


    /* wrong snippet, ignore it

    return array(

      array('username', 'length', 'min'=>10), // want to add minimum rule

    );*/

  }

}

The return value of ClassB rules() is:


array(2) {

  [0]=>

  array(3) {

    [0]=>string(<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/cool.gif' class='bbc_emoticon' alt='8)' /> "username"

    [1]=>string(6) "length"

    ["max"]=>int(20)

  }

  [1]=>

  array(3) {

    [0]=>string(<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/cool.gif' class='bbc_emoticon' alt='8)' /> "username"

    [1]=>string(6) "length"

    ["min"]=>int(10)

  }

}

If I test this rule only the "max" rule is active and the "min" rule is ignored.

In my opinion the output should be:


array(2) {

  [0]=>

  array(3) {

    [0]=>string(<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/cool.gif' class='bbc_emoticon' alt='8)' /> "username"

    [1]=>string(6) "length"

    ["max"]=>int(20)

    ["min"]=>int(10)

  }

}

Thank you for any suggestions/ideas.

My system:

* operating system: Windows Vista


* Web server: XAMPP 1.7.3 with Apache 2.2.14


* browser type: FF 3.6.7


* Yii version or SVN revision: yii-1.1.3.r2247

Did you try to set allowEmpty=>false for the min rule? Otherwhise empty strings would also be accepted which might be your problem.

Oh, i didn’t see that ClassB extends ClassA. It will be hard to merge rules and add more specific validation to the child. You would have to clarify how this merging should happen.

You could try something like this:


  public function rules() {

    $rules=parent::rules();

    return CMap::mergeArray($rules,array(

      array('username', 'length', 'max'=>20), // generated rule cause of varchar(20) db field

    ));

  }



But it will not give you the expected result, i guess. You’d have to analyze the parent rules first and override/add properties from a matching child rule.

First of all thank you for your quick answer’s but I have made a mistake in my initial post (it is corrected now). I have already your Version of Code with CMap::mergeArray() in my Code, I posted the wrong snippet of ClassB Code.

Have it like this with "min" instead of "max" like in your example because "max" is already set in ClassA.


// ClassB rules()

public function rules() {

    $rules=parent::rules();

    return CMap::mergeArray($rules,array(

      array('username', 'length', 'min'=>10),

    ));

  }



The reason for this is that I want to have ClassA to be only the generated Gii Code with less changes as possible. So if the database structure is changed, I have only to generate the ClassA again with Gii and everything should work without or with less changes in ClassB.

Like i said, you can’t use CMap::mergeArray then. You need to loop over all rules and find those, where the attribute name + validator matches. Note here that attribute name can also be a comma separated list of attributes. It’s up to you how you want to treat those rules. Then you need to merge the validator properties manually. It might be best to create a custom helper method for this.

I will think about to write the helper method or simply edit the rules() in the parent Class manually because copying the existing rules to an updated class is a task of just 5 seconds.

Thanks for help mike, topic can be closed.