Как поправить правила валидации?

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
user
Сообщения: 159
Зарегистрирован: 2017.12.05, 16:55

Как поправить правила валидации?

Сообщение user »

Есть класс:

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

    public function addCode()
    {
        return Yii::$app->user->identity->CODE;
    }

    public function convertDate($value)
    {
        return date('Y-m-d H:i:s', $value);
    }

    public function rules()
    {
        return [
            ['CODE', 'filter', 'filter' => [$this, 'addCode']],
            [['latitude', 'longitude', 'date', 'CODE'], 'trim'],
            [['date', 'latitude', 'longitude', 'CODE'], 'required'],
            [['latitude', 'longitude'], 'number', 'numberPattern' => '/^\s*[-+]?[0-9]*\.[0-9]+([eE][-+]?[0-9]+)?\s*$/'],
            ['date', 'integer'],
            ['date', 'filter', 'filter' => [$this, 'convertDate']],
            ['date', 'date', 'format' => 'yyyy-M-d H:m:s'],
            ['date', 'string'],
            [['CODE', 'date'], 'unique', 'targetAttribute' => ['CODE', 'date']]
        ];
    }
передаю "date": "111112222ghj7",
и последнее правило не отрабатывает, а выдает ошибку:
"message": "SQLSTATE[22007]: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Ошибка преобразования даты или времени из символьной строки.\nThe SQL being executed was: SELECT CASE WHEN EXISTS(SELECT * FROM [coordinates] WHERE ([coordinates].

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

='ТМ0006452') AND ([coordinates].[date]='111112222ghj7')) THEN 1 ELSE 0 END",[/quote]
т.е. в последнее правило валидации передается сырое значение date
Аватара пользователя
futbolim
Сообщения: 2051
Зарегистрирован: 2012.07.08, 19:28

Re: Как поправить правила валидации?

Сообщение futbolim »

Всё верно.
Последний ['date', 'string'], отрабатывает, а предыдущие нет. У Вас тут 3 логических ошибки.
Оставьте одно правило, например такое:
['date', 'date', 'format' => 'php:Y-m-d H:i:s']
Вот пример как нужно писать свои валидаторы (не возвращать, а добавлять ошибки, если есть):

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

['base_vote', 'required'],
['base_vote', function() {
    if(!is_float($this->base_vote)) {
        $this->base_vote = (int)$this->base_vote;
        if(!in_array($this->base_vote, range(1, 10))) {
            $this->addError('base_vote', 'Значение базовой оценки неверно.');
        }
    }
}],
В Вашем случае было бы:

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

public function convertDate($attribute)
{
    $dt = DateTime::createFromFormat('asd', $this->{$attribute});
    $this->{$attribute} = $dt->format('Y-m-d H:i:s');
}
П.с. учитесь сразу красиво писать правила. Где Вы CODE будете искать? Глаза разбегаются. Вот пример:

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

['country_id', 'required'],
['country_id', 'integer'],
['country_id', 'exist', 'skipOnError' => true, 'targetClass' => Country::class, 'targetAttribute' => ['country_id' => 'id']],

['city_id', 'required'],
['city_id', 'integer'],
['city_id', 'exist', 'skipOnError' => true, 'targetClass' => City::class, 'targetAttribute' => ['city_id' => 'id']],

['name', 'trim'],
['name', 'required'],
['name', 'string', 'min' => 2, 'max' => 255],

['sex', 'required'],
['sex', 'in', 'range' => [User::SEX_MALE, User::SEX_FEMALE]],

['bday', 'required'],
['bday', 'safe'],

['site_url', 'trim'],
['site_url', 'string', 'min' => 4, 'max' => 70],

['about', 'trim'],
['about', 'string', 'max' => 1000],

[['current_password', 'new_password', 'new_password_repeat'], 'required'],
[['current_password', 'new_password', 'new_password_repeat'], 'string', 'min' => 6],

['new_password_repeat', 'required',
    'when' => function ($model, $attribute) {
        return !empty($model->new_password);
    },
    'whenClient' => 'function (attribute, value) {
        return $("#settingsform-new_password").val().length;
    }'
],
['new_password_repeat', 'compare',
    'compareAttribute' => 'new_password',
    'when' => function ($model, $attribute) {
        return !empty($model->new_password);
    },
    'whenClient' => 'function (attribute, value) {
        return $("#settingsform-new_password").val().length;
    }'
],

['current_password', 'required',
    'when' => function ($model, $attribute) {
        return !empty($model->new_password);
    },
    'whenClient' => 'function (attribute, value) {
        return $("#settingsform-new_password").val().length;
    }'
],
['current_password', 'validateCurrentPassword'],
Помните, что следующий кодер, который будет поддерживать Ваш код может оказаться маньяком, который знает, где Вы живёте ;)
user
Сообщения: 159
Зарегистрирован: 2017.12.05, 16:55

Re: Как поправить правила валидации?

Сообщение user »

Спасибо за развернутый ответ, но возник небольшой нюанс:
public function addCode($attribute)
{
$this->{$attribute} = Yii::$app->user->identity->CODE;
}
Выдает ошибку: "Unknown Property",
Хотя в таблице это поле присутствует
Ответить