问题
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?
回答1:
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();
}
回答2:
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)
来源:https://stackoverflow.com/questions/3859155/is-there-a-way-to-override-model-properties-without-defining-them-all-again-with