валидация в yii-1.1b.r1504

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
Аватара пользователя
kosenka
Сообщения: 677
Зарегистрирован: 2009.09.26, 12:41
Откуда: москва
Контактная информация:

валидация в yii-1.1b.r1504

Сообщение kosenka »

То ли бага, то ли фича. Есть модель с такими правилами:

Код: Выделить всё

        public $password_repeat; // при регистрации, смене пароля

        public function rules()
        {
                return array(
                        array('password','length','max'=>32,'min'=>3), // длина пароля не больше 32 символов
                        array('password','required','on'=>'insert, registration','message'=>Yii::t('lan','Field "{attribute}" incorrect.')),
                        array('password','match','pattern'=>'/^[\w\s]{3,32}$/','message'=>Yii::t('lan','Field "{attribute}" incorrect.')),//паттерн на пароль
                        array('password_repeat','compare','compareAttribute'=>'password','on'=>'registration','message'=>Yii::t('lan','Field "{attribute}" incorrect.')), // проверяем чтобы поле "повторите пароль" совпадало с полем "пароль"
                );
        }
 
и контроллер (вернее кусок, отвечающий за "регистрацию юзеров")

Код: Выделить всё

    public function actionRegistration()
    {       
        $model=new User(); // создаем новую модель User
        $details=new UserDetails(); // создаем новую модель UserDetails
        if(isset($_POST['User']) and isset($_POST['UserDetails'])) // нас послали из формы /themes/[theme_name]/views/user/registration.php ?
        {
                $model->setScenario('registration');//устанавливаем сценарий проверки
                $details->setScenario('registration');//устанавливаем сценарий проверки

                $model->attributes=$_POST['User']; // присваивание данных для модели User
                $details->attributes=$_POST['UserDetails']; //  присваивание данных для модели UserDetails

                $validate_m=$validate_d=TRUE; // признак того, что валидация моделей: User, UserDetails прошла успешно
                
                if(!$model->validate()) // проверяем модель User
                {
                        $validate_m=FALSE; // валидация не прошла
                }

                if(!$details->validate())  // проверяем модель UserDetails
                {
                        $validate_d=FALSE; // валидация не прошла
                }

                if($validate_m===TRUE and $validate_d===TRUE)//валидация моделей User, UserDetails прошла успешно?
                {
                        // да,валидация моделей User, UserDetails прошла успешно
                        $password=$model->password;//сохраняем пароль, чтобы отослать юзеру
                        $model->password=md5($password);// шифруем пароль
                        $model->password_repeat=md5($model->password_repeat);//шифруем "повторите пароль", что при записи сработала валидация password==password_repeat;
                        if($model->save())
                        {
                        }//if($model->save())
                }//if($validate_m and $validate_d)
        }//if(isset($_POST['User']) and isset($_POST['UserDetails']))
        
        $this->render('registration',array('model'=>$model,'details'=>$details)); // показываем форму регистрации - /themes/[theme_name]/views/user/registration.php
    }
 
так вот, когда юзер прошел все этапы валидации и попал "во внутрь"

Код: Выделить всё

if($validate_m===TRUE and $validate_d===TRUE)//валидация моделей User, UserDetails прошла успешно?
 
то почему-то при $model->save() , валидация проходит еще раз. Т.е., если убрать строку:

Код: Выделить всё

$model->password_repeat=md5($model->password_repeat);
 
то $model->save() будет выдавать ошибку "Поле password_repeat заполнено неверно".

В yii 1.0.10 такого не было, раз валидация прошла, то при вызове $model->save() никакой "повторной валидации не было" или я ошибаюсь?
Ekstazi
Сообщения: 1428
Зарегистрирован: 2009.08.20, 22:54
Откуда: Молдова, Бельцы
Контактная информация:

Re: валидация в yii-1.1b.r1504

Сообщение Ekstazi »

Ошибаешься. там параметром к save указываешь, проверять или нет.
Аватара пользователя
kosenka
Сообщения: 677
Зарегистрирован: 2009.09.26, 12:41
Откуда: москва
Контактная информация:

Re: валидация в yii-1.1b.r1504

Сообщение kosenka »

Ekstazi писал(а):Ошибаешься. там параметром к save указываешь, проверять или нет.
Ну, а почему тогда в yii 1.0.10 тот же самый код, но без строки: $model->password_repeat=md5($model->password_repeat);
работает "как надо" (т.е. не проверяет при $model->save() еще раз всё) ?
Ekstazi
Сообщения: 1428
Зарегистрирован: 2009.08.20, 22:54
Откуда: Молдова, Бельцы
Контактная информация:

Re: валидация в yii-1.1b.r1504

Сообщение Ekstazi »

На сколько я помню, проверялось.
Dreammaker
Сообщения: 139
Зарегистрирован: 2009.09.02, 16:21
Откуда: Черкассы, Украина

Re: валидация в yii-1.1b.r1504

Сообщение Dreammaker »

мне тоже кажется, что валидация проводилась повторно, если не указать "false".
Аватара пользователя
kosenka
Сообщения: 677
Зарегистрирован: 2009.09.26, 12:41
Откуда: москва
Контактная информация:

Re: валидация в yii-1.1b.r1504

Сообщение kosenka »

а где можно посмотреть api для версии 1.0.10 ?
Аватара пользователя
kosenka
Сообщения: 677
Зарегистрирован: 2009.09.26, 12:41
Откуда: москва
Контактная информация:

Re: валидация в yii-1.1b.r1504

Сообщение kosenka »

да, $model->save(false), при записи не делает валидацию. но тогда не понятно, почему в 1.0.10 по другому...
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: валидация в yii-1.1b.r1504

Сообщение samdark »

Аватара пользователя
kosenka
Сообщения: 677
Зарегистрирован: 2009.09.26, 12:41
Откуда: москва
Контактная информация:

Re: валидация в yii-1.1b.r1504

Сообщение kosenka »

Спасибо.
Посмотрел api - ну прям мистика какая-то. Не понимаю, как один и тот же код, но в разных версиях "работает" по разному, хотя должен отрабатывать одинаково...
Аватара пользователя
Ozzy
Сообщения: 269
Зарегистрирован: 2009.04.02, 15:09
Откуда: Украина, Одесса

Re: валидация в yii-1.1b.r1504

Сообщение Ozzy »

АПИ просто расширяется, меняется. Отсюда и такая фигня.
Тоже самое с validate() когда раньше в нем указывалось название сценария прямо внутри, а теперь через $modelObj->scenario
Мой маленький блог - http://dbhelp.ru
Аватара пользователя
kosenka
Сообщения: 677
Зарегистрирован: 2009.09.26, 12:41
Откуда: москва
Контактная информация:

Re: валидация в yii-1.1b.r1504

Сообщение kosenka »

Ozzy писал(а):АПИ просто расширяется, меняется. Отсюда и такая фигня.
Тоже самое с validate() когда раньше в нем указывалось название сценария прямо внутри, а теперь через $modelObj->scenario
нее, теперь через $modelObj->setScenario('сценарий')
:)
Аватара пользователя
Ozzy
Сообщения: 269
Зарегистрирован: 2009.04.02, 15:09
Откуда: Украина, Одесса

Re: валидация в yii-1.1b.r1504

Сообщение Ozzy »

Можно менять через метод, можно напрямую в атрибут.
По сути, одно и тоже.
Мой маленький блог - http://dbhelp.ru
wra
Сообщения: 37
Зарегистрирован: 2009.10.28, 13:48

Re: валидация в yii-1.1b.r1504

Сообщение wra »

У меня такой вопрос: при сохранении новой AR в контроллере в методе actionCreate() вызывается только save() (без предворительного валидата).
Процесс валидации срабатывает как надо. Одним из пунктов rules() у меня стоит собственный метод exist($attribute, $params). В нем я делаю необходимые проверки. Если в нем все в порядке, то я одному из полей модели присваиваю некое значение

Код: Выделить всё

$this->messageTargetUserId = 10; 
Но далее, при непосредственном сохранении, оно теряется. Если это присваивание засунуть в beforeSave(), то все работает как надо.

Вопрос: можно ли в валидаторе (в своем методе) устанавливать значения определенных атрибутов AR? Или что то не так делаю?
Ekstazi
Сообщения: 1428
Зарегистрирован: 2009.08.20, 22:54
Откуда: Молдова, Бельцы
Контактная информация:

Re: валидация в yii-1.1b.r1504

Сообщение Ekstazi »

CDefaultValueValidator
beforeValidate
CActiveRecordBehavior

Выбирай, способов уйма. И все здесь уже обсуждались
wra
Сообщения: 37
Зарегистрирован: 2009.10.28, 13:48

Re: валидация в yii-1.1b.r1504

Сообщение wra »

beforeSave() в целом подходит, но во моем валидаторе происходит проверка на наличие некоторого значения (выбираю из БД через exists()). А потом в beforeSave() читаю строку с теми же критериями. Т.о. выходит 2 запроса к БД. Но если прямо в валидаторе прочить значение и записать в атрибут AR то будет только один запрос.
Ekstazi
Сообщения: 1428
Зарегистрирован: 2009.08.20, 22:54
Откуда: Молдова, Бельцы
Контактная информация:

Re: валидация в yii-1.1b.r1504

Сообщение Ekstazi »

Напиши свой валидатор(класс или метод).
wra
Сообщения: 37
Зарегистрирован: 2009.10.28, 13:48

Re: валидация в yii-1.1b.r1504

Сообщение wra »

Посмотрите кусок кода модели (messageReceivers — в переменную юзер вносит имя пользователя получателя сообщения, в базу ляжет его ID):

Код: Выделить всё

public $messageReceivers;
...
    public function rules()
    {
        return array(
            ...
            array('messageReceivers', 'exist'),
        );
    } 
Валидатор:

Код: Выделить всё

    public function exist($attribute, $params)
    {
        if(!$this->hasErrors())
        {
            if(!Users::model()->exists(array('condition'=>"userName = '".$this->messageReceivers."'")))
                $this->addError('messageReceivers','Указанный получатель не найден!');
        }
    } 
И обработчик:

Код: Выделить всё

    protected function beforeSave()
    {
        ...
        $tu=Users::model()->findByAttributes(array('userName'=>$this->messageReceivers));
        $this->messageTargetUserId = $tu->userId;
        return true;
    } 
Если валидатор сделать так:

Код: Выделить всё

    public function exist($attribute, $params)
    {
        if(!$this->hasErrors())
        {
            //не проверяем есть ли, а выбираем по условию
            $targetUser = Users::model()->findByAttributes(array('userName'=>$this->messageReceivers));

            if ($targetUser)
                $this->messageTargetUserId = $targetUser->userId;
            else
                $this->addError('messageReceivers','Указанный «Получатель» не найден!');
        }
    } 
то содерживое из function beforeSave() уже не нужно. Но если я делаю по такому методу, то при сохранении теряется

Код: Выделить всё

$this->messageTargetUserId = $targetUser->userId; 
Поэтому и был вопрос: что я делаю не так?
Ответить