Задать вопрос
@site_trouble

Почему Yii подставляет пустую строку вместо null?

Добрый день. Столкнулся с не очень очевидным поведением. При вставке данных в таблицу (model->save()) происходит замена того что должно быть null на пустую строку, а именно поля "email". Почему так происходит? Как изменить это поведение?
/* Правила */
 public function rules()
    {
        return [
            ['status', 'default', 'value' => self::STATUS_ACTIVE],
            ['device_type', 'default', 'value' => self::DEVICE_WEB],

            [
                [
                    'created_at',
                    'updated_at',
                    'device_type',
                    'status',
                    'issue_code'
                ],
                'integer'
            ],
            [
                [
                    'username',
                    'password_hash',
                    'password_reset_token',
                    'email',
                ],
                'string',
                'max' => 255
            ],
            [['uuid', 'auth_key'], 'string', 'max' => 32],
            ['device_name', 'string', 'max' => 255],
            ['registration_ip', 'string', 'max' => 45],

            ['phone', 'string', 'max' => 10],
            ['phone', 'match', 'pattern' => '#^\d+$#i'],
            ['phone', 'unique', 'message' => 'Телефон уже существует.'],

            ['email', 'filter', 'filter' => 'trim'],
            ['email', 'email'],
            ['email', 'unique', 'message' => 'Email уже существует.'],

            ['username', 'filter', 'filter' => 'trim'],
            [
                'username',
                'unique',
                'message' => 'Имя пользователя уже существует.'
            ],
            ['username', 'string', 'min' => 2, 'max' => 255],

            ['status', 'in', 'range' => array_keys(self::getStatusesArray())],
            [
                'device_type',
                'in',
                'range' => array_keys(self::getDeviceTypesArray())
            ],
        ];
    }
/* Простой код */
$user = new User();
$user->username = '123';
// тут сеттим остальные поля, кроме email
$user->save();

/* Ошибка, само собой индексы дублируются т.к. там не NULL */
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '' for key 'idx_user_email'
 The SQL being executed was: INSERT INTO `user` (`auth_key`, `password_hash`, `username`, `email`, `status`, `device_type`, `created_at`, `updated_at`, `registration_ip`) VALUES ('123', '123', '123', '', 1, 0, 1533732859, 1533732859, '192.168.1.1')


Что пробовал сделать:
/* rules */
['email', 'default', 'value' => null]
/* перед $user->save() */
$user->email = null;
  • Вопрос задан
  • 1394 просмотра
Подписаться 1 Средний Комментировать
Решения вопроса 1
@site_trouble Автор вопроса
Решение:
['email', 'filter', 'filter' => 'trim'], // trim приводит null  к пустой строке
['email', 'email'],
['email', 'unique', 'message' => 'Email уже существует.'],
// либо добавляем правило
['email', 'default', 'value' => null], // по умолчанию ставим null. Важно чтобы это правило было после trim
// либо изменяем trim
['email', 'filter', 'filter' => 'trim', 'skipOnEmpty' => true],

Дока:

When the validate() method is called, it does the following steps to perform validation:

Determine which attributes should be validated by getting the attribute list from yii\base\Model::scenarios() using the current scenario. These attributes are called active attributes.
Determine which validation rules should be used by getting the rule list from yii\base\Model::rules() using the current scenario. These rules are called active rules.
Use each active rule to validate each active attribute which is associated with the rule. The validation rules are evaluated in the order they are listed.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
usdglander
@usdglander
Yipee-ki-yay
Ну так а в самой таблице поле email может быть NULL?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы