Страница 1 из 1

authenticate в rules()

Добавлено: 2010.09.15, 11:37
xstupid_kidzx
Приветсвую!

Изучая статью (раздел "Определение правил проверки"), руководство по созданию блога и пробуя все это на практике, я обнаружил, что валидация authenticate будет вызываться всегда, независимо от того, валидны ли все предыдущие правила:

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

class LoginForm extends CFormModel
{
    public $username;
    public $password;
    public $rememberMe;

    private $_identity;

    public function rules()
    {
        return array(
            array('username, password', 'required'),
            array('rememberMe', 'boolean'),
            array('password', 'authenticate'),
        );
    }

    public function authenticate($attribute,$params)
    {
        $this->_identity=new UserIdentity($this->username,$this->password);
        if(!$this->_identity->authenticate())
            $this->addError('password','Incorrect username or password.');
    }

 
Таким образом, даже если я не введу данные в поля логина и пароля, то все равно будет обращение в БД, которое констатирует ошибку отсутсвия пользователя.

Отсюда вопрос - можно ли предотвратить проверку оставшихся правил, если провалилось первое, либо нужно убрать из правил валидацию authenticate и провести ее после того, как мы убедимся, что все поля введены корректно?

Re: authenticate в rules()

Добавлено: 2010.09.15, 12:01
BuCeFaL
в методе auth. можно поставить условие перед запросом в базу на отсуцтвие ошибок.
http://www.yiiframework.com/doc/api/CModel#hasErrors hasErrors

Re: authenticate в rules()

Добавлено: 2010.09.15, 12:11
Dr0ID
было бы не плохо, если бы в правила валидации добавить еще параметр который бы отвечал за данную ситуацию, например noErrorsBefore (или что-то подобное). По дефолту false, а если установить в true, то такие правила будут валидироваться только если до этого не было ошибок. Соответственно их надо будет добавлять в конец списка правил.

Отличная фича получится, а то у меня в одной модели 4 проверки на уникальность полей в других моделях (unique - CUniqueValidator), соответственно выполняется 4 запроса независимо от того были ли ошибки.

Re: authenticate в rules()

Добавлено: 2010.09.15, 12:23
xstupid_kidzx
BuCeFaL писал(а): в методе auth. можно поставить условие перед запросом в базу на отсуцтвие ошибок.
http://www.yiiframework.com/doc/api/CModel#hasErrors hasErrors
Спасибо! Забыл совсем про данный метод.
Dr0ID писал(а): Отличная фича получится, а то у меня в одной модели 4 проверки на уникальность полей в других моделях (unique - CUniqueValidator), соответственно выполняется 4 запроса независимо от того были ли ошибки.
А как ты с этим сейчас борешься?

Re: authenticate в rules()

Добавлено: 2010.09.15, 12:39
Dr0ID
Пока никак. Проект еще на dev стадии, потом буду заниматься оптимизацией.

Re: authenticate в rules()

Добавлено: 2010.09.15, 13:53
BuCeFaL
такое свойство есть и его наследуют все валидаторы. По умолчанию выключено.
http://www.yiiframework.com/doc/api/CVa ... kipOnError skipOnError

Re: authenticate в rules()

Добавлено: 2010.09.15, 14:01
xstupid_kidzx
BuCeFaL писал(а):такое свойство есть и его наследуют все валидаторы. По умолчанию выключено.
http://www.yiiframework.com/doc/api/CVa ... kipOnError skipOnError

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

/* CValidator.php */

/**
     * @var boolean whether this validation rule should be skipped if when there is already a validation
     * error for the current attribute. Defaults to false.
     * @since 1.1.1
     */
    public $skipOnError=false;
 
Таким образом, правило пропускается только в том случае, если для указанного атрибута ошибка уже произошла.

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

//$username = 'user';
//$password = 'pass';

public function rules()
    {
        return array(
            array('username, password', 'required'),
            array('password', 'numerical'),
            array('password', 'authenticate', 'skipOnError' => true), //ПРОПУСК СРАБОТАЕТ
        );
    }

/*************************************************************************************/

public function rules()
    {
        return array(
            array('username, password', 'required'),
            array('password', 'numerical'),
            array('username', 'authenticate', 'skipOnError' => true), //ПРОПУСК НЕ СРАБОТАЕТ
        );
    }