Почему в методе rules() атрибуты равны null
Попытаюсь объяснить это в этом рецепте, и возможно сохранить время новичкам, а так же тем кто не пропускает ни одной темы на форуме.Как мне в rules() добавлять правила в зависимости от значения атрибута (поле формы)
Метод rules() нужен для создания валидаторов. Этот метод вызывается один раз, перед тем как, ВНИМАНИЕ, будет первый раз нужен этот список валидаторов, а не перед непосредственно валидацией.
Когда же первый раз нужен список валидаторов, спросите Вы? Разве не перед валидацией?
Нет. Список валидаторов может понадобится в behaviors, events, да в общем говоря, везде в коде.
В фреймворке, по умолчанию список валидаторов первый раз нужен ДО массового присвоения значений
Код: Выделить всё
$model->attributes = ...
Повторю, список нужен ДО массового присвоения. Т.е. когда значения у атрибутов еще НЕ установлены.
Было не правильно до массового присвоения создавать один список, а перед валидацией другой. Не находите?
Как же быть если нужны динамические правила? На это случай фреймворк предоставляет Вам сразу 3 возможности. Выбирайте понравившийся или более подходящую под конкретную задачу.
1) Сценарии
Код: Выделить всё
public function rules()
{
$rules = array();
if ($this->scenario === 'scenario1') {
$rules[] = array('attribute', 'required', 'requiredValue' => 'value1');
} elsef ($this->scenario === 'scenario2') {
$rules[] = array('attribute', 'required', 'requiredValue' => 'value2');
}
return $rules;
}
Код: Выделить всё
public function rules()
{
return array(
array('attribute', 'validateAttribute', 'on' => 'insert, update', 'message' => 'Не верный атрибут');
);
}
public function validateAttribute($attribute, array $params = array())
{
$error = isset($params['message']) ? $params['message'] : 'Invalid attribute';
if ($this->type === 'type1' && $this->$attribute !== 'value1') {
$this->addError($attribute, $error);
} elseif ($this->type === 'type2' && $this->$attribute !== 'value2') {
$this->addError($attribute, $error);
}
}
Код: Выделить всё
public function dynamicRules()
{
$rules = array();
if ($this->category === 'website') {
$rules[] = array('value', 'url', 'on' => 'insert, update',);
} elseif ($this->category === 'mail') {
$rules[] = array('value', 'email', 'on' => 'insert, update',);
}
return $rules;
}
protected function beforeValidate()
{
if (!parent::beforeValidate()) {
return false;
}
foreach ($this->dynamicRules() as $params) {
$attribute = array_shift($params);
$name = array_shift($params);
$validator = CValidator::createValidator($name, $this, $attribute, $params);
$this->validatorList->add($validator);
}
return true;
}