Дефолтное значение из таблицы не попадает в модель

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
azz
Сообщения: 197
Зарегистрирован: 2016.07.06, 17:20

Дефолтное значение из таблицы не попадает в модель

Сообщение azz »

Приветствую.
Модель

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

class Menu extends \yii\db\ActiveRecord {

    /**
     * @inheritdoc
     */
    public static function tableName() {
        return 'menu';
    }

    /**
     * @inheritdoc
     */
    public function rules() {
        return [
            [['parent_id', 'name', 'display_url'], 'required'],
            [['parent_id', 'items_order', 'can_be_deleted', 'is_hidden'], 'integer'],

            [['name', 'inner_url', 'display_url'], 'string', 'max' => 200],
            [['name', 'inner_url', 'display_url'], 'trim'],
            [['display_url'], 'unique'],
        ];
    }
контроллер

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

    public function actionCreate() {
        $model = new Menu();
        if ($model->load(Yii::$app->request->post()) && $model->save()) {
таблица

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

DROP TABLE IF EXISTS `menu`;
CREATE TABLE `menu` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `parent_id` int(10) unsigned NOT NULL,
  `items_order` int(10) unsigned NOT NULL DEFAULT '0',
  `name` varchar(200) NOT NULL,
  `inner_url` varchar(200) NOT NULL DEFAULT 'site/custom',
  `display_url` varchar(200) NOT NULL,
  `can_be_deleted` tinyint(4) NOT NULL DEFAULT '1',
  `is_hidden` tinyint(4) NOT NULL DEFAULT '1',
  PRIMARY KEY (`id`),
  UNIQUE KEY `url` (`display_url`),
  KEY `parent_id` (`parent_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Если items_order в форме не заполнять, то вываливается ошибка

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

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'items_order' cannot be null
если убрать items_order из rules, то запись добавляется без проблем с дефолтным значением поля. Но мне нужно его проверять. Без дублирования дефолтного значения в rules, никак?
Аватара пользователя
maleks
Сообщения: 1985
Зарегистрирован: 2012.12.26, 12:56

Re: Дефолтное значение из таблицы не попадает в модель

Сообщение maleks »

$model->->loadDefaultValues() после создания модели
Yii2 universal module sceleton - for basic and advanced templates
azz
Сообщения: 197
Зарегистрирован: 2016.07.06, 17:20

Re: Дефолтное значение из таблицы не попадает в модель

Сообщение azz »

maleks писал(а): 2017.12.15, 17:48 $model->->loadDefaultValues() после создания модели
не срабатывает, вызывают так

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

    public function actionCreate() {
        $model = new Menu();
        $model->loadDefaultValues();

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
хотя если вывести модель после создания там всё нормально

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

common\models\Menu#1
(
    [yii\db\BaseActiveRecord:_attributes] => [
-->    'items_order' => '0'
        'admin_url' => 'custom-page/update'
        'controller' => 'site'
        'inner_url' => 'site/custom'
        'can_be_deleted' => 1
        'is_hidden' => 1
        'is_content_page' => 1
    ]
    [yii\db\BaseActiveRecord:_oldAttributes] => null
    [yii\db\BaseActiveRecord:_related] => []
    [yii\base\Model:_errors] => null
    [yii\base\Model:_validators] => null
    [yii\base\Model:_scenario] => 'default'
    [yii\base\Component:_events] => []
    [yii\base\Component:_behaviors] => []
)
:shock:

ну т.е. как не срабатывает. Оно выводит теперь в форме для этого поля дефолтное значение "0". Если его не трогать, запись добавляется. Если его удалить, то вываливается ошибка.

Ещё момент. В базе есть несколько полей, которые имеют значение по умолчанию в таблице, собственно все в дампе видны.
Они заполняются без проблем, даже если не делать $model->loadDefaultValues()
items_order, единственное проблемное поле из них, присутствует для заполнения пользователем в форме:

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

    <?= $form->field($model, 'items_order')->textInput(['maxlength' => true]) ?>
Если его удалить из формы, всё налаживается. Не баг ли это во фреймворке?
Аватара пользователя
tugrik
Сообщения: 26
Зарегистрирован: 2016.03.11, 17:07

Re: Дефолтное значение из таблицы не попадает в модель

Сообщение tugrik »

Все верно работает:
Если Вы посмотрите запрос который сохраняет\апдейтит вашу запись, Вы увидете что у вас в запросе

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

 ... set `parent_id` = null ... 
, а в базе

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

 `parent_id` int(10)  
без nullable.
azz
Сообщения: 197
Зарегистрирован: 2016.07.06, 17:20

Re: Дефолтное значение из таблицы не попадает в модель

Сообщение azz »

ElisDN писал(а): 2017.12.18, 13:34

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

['items_order', 'default', 'value' => 0],
как раз вопрос в том, что бы не дублировать дефолтные значения, уже прописанные в таблице, в rules модели
tugrik писал(а): 2017.12.18, 13:38 Все верно работает:
Если Вы посмотрите запрос который сохраняет\апдейтит вашу запись, Вы увидете что у вас в запросе

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

 ... set `parent_id` = null ... 
, а в базе

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

 `parent_id` int(10)  
без nullable.
так он же сам мне пишет в дампе: 'items_order' => '0', а потом оно вдруг становится NULL, причём это только то поле, что пришло из формы. Я примерно понимаю почему так, но не понимаю как (и можно ли это исправить) без

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

['items_order', 'default', 'value' => 0],
Аватара пользователя
tugrik
Сообщения: 26
Зарегистрирован: 2016.03.11, 17:07

Re: Дефолтное значение из таблицы не попадает в модель

Сообщение tugrik »

Для начала, хорошо бы было отделить модель AR от бизнес логики (Ваших форм, которые вы редактируете).
Но вся же, если хотите на костылях, попробуйте:

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

['parent_id',  'filter' => 'intval', 'skipOnEmpty' => true],
или

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

 ['parent_id', 'required', 'isEmpty' => function ($value) {
        return 0;
    }]
Но не уверен что сработает
azz
Сообщения: 197
Зарегистрирован: 2016.07.06, 17:20

Re: Дефолтное значение из таблицы не попадает в модель

Сообщение azz »

tugrik писал(а): 2017.12.18, 15:06 Для начала, хорошо бы было отделить модель AR от бизнес логики (Ваших форм, которые вы редактируете).
Вы о чём?
Ответить