views:

65

answers:

2

I have the following, for example:

class Model_User extends ORM {
    protected $_rules = array(
        'username' => array(
            'not_empty'  => NULL,
            'min_length' => array(6),
            'max_length' => array(250),
            'regex'      => array('/^[-\pL\pN_@.]++$/uD'),
        ),
        'password' => array(
            'not_empty'  => NULL,
            'min_length' => array(5),
            'max_length' => array(30),
        ),
        'password_confirm' => array(
            'matches'    => array('password'),
        ),
    );
}

class Model_UserAdmin extends Model_User {
    protected $_rules = array(
        'username' => array(
            'not_empty'  => NULL,
            'min_length' => array(6),
            'max_length' => array(250),
            'regex'      => array('/^[-\pL\pN_@.]++$/uD'),
        ),
        'password' => array(
            'not_empty'  => NULL,
            'min_length' => array(5),
            'max_length' => array(42),
        ),
    ); 
}

In here, Model_UserAdmin extends Model_User and overrides the max length for password and removes the validation for password_confirm (this is not an actual case, but an example).

Is there a better way instead of redefining the entire $_rules property/array?

+2  A: 

In the child's constructor you can probably overwrite or add array elements to $this->_rules, as it will already exist as soon as you create a Model_UserAdmin instance.

Specifically, in Model_UserAdmin don't define a protected $rules so it gets it from its parent, and then in the constructor:

$this->_rules['password']['max_length'] = 42 ;
unset($this->_rules['password_confirm']) ;

You can also add some sanity check right before to make sure those keys exist, in case you change them in Model_User and forget.

It's not exactly elegant but it should work. I do suppose you can create some wrapper functions around it (probably in a class ORM extends ORM_Core so they're available when you extend ORM) that modify the rules in a more formal way.

edit please look at biakaveron's answer for a tip on where to place the child rules (_initialize() instead of the constructor)

Fanis
I was thinking this would be the way :( Was hoping Kohana had something for this already.
Darryl Hein
+4  A: 

Use _initialize() instead of __construct($id) if you want to store your UserAdmin model in session (like Auth module does). Serialized ORM objects will not call __construct(), so part of your rules will lost. _initialize() method sets default values for model properties like table_name, relationships etc

protected function _initialize()
{
   // redefine model rules
   $this->_rules['password']['max_length'] = 42 ;
   unset($this->_rules['password_confirm']) ;
   // call parent method
   parent::_initialize();
}
biakaveron