Comments 12
Спасибо за статью.
от бы еще на клиент эти динамические правила передать, чтобы для подсветки required поля не делать лишний запрос.
от бы еще на клиент эти динамические правила передать, чтобы для подсветки required поля не делать лишний запрос.
А почему у вас в коде есть параметр validateOnSubmit но нету afterValidate? Или это описка?
Не понял зачем вы поместили код изменения сценария в метод performAjaxValidation. В этом случае сценарий не будет использован если форму отправили обычным способом. Я бы сделал так
Не понял зачем вы поместили код изменения сценария в метод performAjaxValidation. В этом случае сценарий не будет использован если форму отправили обычным способом. Я бы сделал так
public function actionSaveCall(){
$model=new Calls('callSubmit');
if( isset($_POST['Calls']) && isset($_POST['Calls']['call_status']) ) {
switch($_POST['Calls']['call_status']) {
case Calls::CALL_FAIL:
$model->setScenario('validCallSubmit');
break;
case Calls::SUCCESS_CALL:
$model->setScenario('successCallSubmit');
break;
case Calls::WRONG_NUMBER:
$model->setScenario('invalidNumberSubmit');
break;
}
$this->performCallAjaxValidation($model);
...
}
}
мда красиво оно отформатировало. Для тех кому лень вставлять «это» в редактор я вынес установку сценария в метод actionSaveCall перед вызовом метода performCallAjaxValidation
Если сценариев будет много, то довольно накладно будет писать много конструкций case.
Тут недостаток в другом — что я не сделал это в ООП-манере и не вынес этот массив и само изменение сценария из метода performAjaxValidation, но я предупредил о том, что не заморачиваюсь об этом. В идеале этот массив лучше было ы хранить в определенном конфиге и вытягивать его в свойство модели в методе __construct().
Тут недостаток в другом — что я не сделал это в ООП-манере и не вынес этот массив и само изменение сценария из метода performAjaxValidation, но я предупредил о том, что не заморачиваюсь об этом. В идеале этот массив лучше было ы хранить в определенном конфиге и вытягивать его в свойство модели в методе __construct().
Если сценариев будет много возникнет другая проблема. Прописывать правила валидации для большого количества сценариев очень неудобно в том виде как это реализовано в Yii
Ну для того чтобы запилить в метод rules много сценариев валидации, можно вынести их из модели в какой-то легко читаемый конфиг, например в формате YAML (.yml), и потом из этого конфига читать эти правила при инициализации модели. Алгоритм прост — читается конфиг, превращается в массив, делается implode(",", $configArray), массив всех правил, возвращаемых методом rules берется в свойство, и затем все правила, которые нужно добавить, добавляются туда с помощью array_push(). Ну а сам метод rules возвращает это свойство.
Но вы правы, эту работу нужно проделать самому. Правда и то, что в Yii разделение логики более слабое, нежели в том же Symfony2.
Но вы правы, эту работу нужно проделать самому. Правда и то, что в Yii разделение логики более слабое, нежели в том же Symfony2.
Мне не кажется способ вынесения правил валидации в отдельный файл хорошим решением. Тем более что в остальных моделях правила находятся в их классе. А вообще нет ничего удивительного что в yii не так удобно работать с большим количеством сценариев. Этот случай на столько редкий что жертвовать красотой настройки ради этих случаев глупо. Тем более что даже в тех случаях проблема скорее в не правильном написании кода чем в необходимости. Я уверен что сценариев не должно быть много.
>>Мне не кажется способ вынесения правил валидации в отдельный файл хорошим решением.
На самом деле это хорошее и правильное решение, так как способствует еще большему разделению ответственности и логики на понятные составляющие. Но вы правы в том, что все должно быть по одному стандарту — если выносить правила, то тогда уже во всех моделях.
В симфони все это выносится в отдельные сущности, правда вам для этого не нужно писать код для обработки этих сущностей, так как это разделение заложено в фреймворке. И должен сказать, по поводу «жертвовать красотой» вы не правы, так как такое разделение в симфони выглядит значительно красивее чем метод rules в моделях в Yii — это и читабельнее, и красивее, и гибче.
На самом деле это хорошее и правильное решение, так как способствует еще большему разделению ответственности и логики на понятные составляющие. Но вы правы в том, что все должно быть по одному стандарту — если выносить правила, то тогда уже во всех моделях.
В симфони все это выносится в отдельные сущности, правда вам для этого не нужно писать код для обработки этих сущностей, так как это разделение заложено в фреймворке. И должен сказать, по поводу «жертвовать красотой» вы не правы, так как такое разделение в симфони выглядит значительно красивее чем метод rules в моделях в Yii — это и читабельнее, и красивее, и гибче.
Да, кстати, спасибо большое на ценное указание по поводу afterValidate — после валидации желательно убрать «зеленую подсветку» у тех полей, у которых она осталась с прошлых валидаций. Добавлю в пост скоро.
имхо, вы выбрали неверный путь для валидации полей зависящих от значения других полей.
недостатки:
1. теряется наглядность при изучении модели
2. нужно создавать дополнительный код в котроллере для обеспечения смены сценария
3. что если кто то переименует сценарии?
На мой взгляд задача довольно очевидная — «Обеспечить валидацию полей зависимых от значения других полей».
Т. е. нужно создать новый клас валидации (конечно же унаследовав существующий валидатор), и добавить ему функционал, который позволит обрабатывать ситуации в зависимости от других параметров.
вот пример такого валидатора:
ну и правила в модели:
недостатки:
1. теряется наглядность при изучении модели
2. нужно создавать дополнительный код в котроллере для обеспечения смены сценария
3. что если кто то переименует сценарии?
На мой взгляд задача довольно очевидная — «Обеспечить валидацию полей зависимых от значения других полей».
Т. е. нужно создать новый клас валидации (конечно же унаследовав существующий валидатор), и добавить ему функционал, который позволит обрабатывать ситуации в зависимости от других параметров.
вот пример такого валидатора:
class ExRequiredValidator extends CRequiredValidator{
public $strict = true;
/**
* makes validation depend on some another attribute value
* useful when some fileds of form are hidden based on appropriate attribute
* @var string
*/
public $boundAttribute = null;
/**
* @var string
*/
public $boundAttributeValue = null;
ну и правила в модели:
public function rules(){
return array(
array('call_status','required','message'=>'Required field'),
array('talk_status','ExRequiredValidator','boundAttribute'=>'call_status','boundAttributeValue'=>'success','message'=>'Required field'),
);
}
видимо правила в модели не влезли на страницу:
public function rules(){
return array(
array('call_status','required','message'=>'Required field'),
array('talk_status','ExRequiredValidator','boundAttribute'=>'call_status','
boundAttributeValue'=>'success','message'=>'Required field'),
);
}
Sign up to leave a comment.
Yii: Динамическое изменение правил валидации (сценариев)