S
S
site_trouble2018-08-08 16:11:33
This
site_trouble, 2018-08-08 16:11:33

Why does Yii substitute an empty string for null?

Good afternoon. Faced with not very obvious behavior. When inserting data into the table (model->save()), what should be null is replaced with an empty string, namely the "email" field. Why is this happening? How to change this behavior?

/* Правила */
 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')

What I tried to do:
/* rules */
['email', 'default', 'value' => null]
/* перед $user->save() */
$user->email = null;

Answer the question

In order to leave comments, you need to log in

[[+comments_count]] answer(s)
S
site_trouble, 2018-08-08
@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.

L
Lander, 2018-08-08
@usdglander

Ну так а в самой таблице поле email может быть NULL?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question