yii2-save-relations-behavior и валидация

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Аватара пользователя
webplus
Сообщения: 245
Зарегистрирован: 2012.02.24, 22:05
Контактная информация:

yii2-save-relations-behavior и валидация

Сообщение webplus » 2018.03.03, 12:37

Здравствуйте!
Для сохранения связей использую поведение https://github.com/la-haute-societe/yii ... s-behavior
Все работает успешно.
Но я захотел проверить переданные данные из формы в модели

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

[['catalog'], 'each', 'rule' => ['exist', 'skipOnError' => true, 'targetClass' => Catalog::className(), 'targetAttribute' => 'id']]
или

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

[['catalog'], 'each', 'rule' => ['integer']],
Но выдает ошибку валидации: Значение «catalog» должно быть целым числом.

Если сделать print_r данных POST то там виден массив ключ => значение

в вьюхе:

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

                <?= $form->field($model, 'catalog')->widget(Select2::classname(), [
                    'data' => ArrayHelper::map(Catalog::find()->orderBy('sort ASC')->all(), 'id', 'name'),
                    'language' => 'ru',
                    'options' => ['placeholder' => 'Выберите категорию ...', 'multiple' => true],
                    'toggleAllSettings' => [
                        'selectLabel' => null,
                    ],
                    'pluginOptions' => [
                        'allowClear' => true
                    ],
                ]);?>
в модели

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

    public function getCatalog()
    {
        return $this->hasMany(Catalog::className(), ['id' => 'catalog_id'])->viaTable(UserCatalog::tableName(), ['user_id' => 'user_id']);
    }
Почему может не работать валидация?

andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: yii2-save-relations-behavior и валидация

Сообщение andku83 » 2018.03.03, 17:26

как выглядит ваша форма когда у вашего Юзера есть несколько каталогов?

Аватара пользователя
webplus
Сообщения: 245
Зарегистрирован: 2012.02.24, 22:05
Контактная информация:

Re: yii2-save-relations-behavior и валидация

Сообщение webplus » 2018.03.03, 19:03

shnir писал(а):
2018.03.03, 17:26
как выглядит ваша форма когда у вашего Юзера есть несколько каталогов?
вот так http://joxi.ru/VrwzRWvCKn998A

andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: yii2-save-relations-behavior и валидация

Сообщение andku83 » 2018.03.03, 20:42

попробуйте вот так:

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

                <?= $form->field($model, 'catalog[]')->widget(Select2::classname(), [
если не получится, тогда покажите как к вам приходят данные в POST

Аватара пользователя
webplus
Сообщения: 245
Зарегистрирован: 2012.02.24, 22:05
Контактная информация:

Re: yii2-save-relations-behavior и валидация

Сообщение webplus » 2018.03.03, 23:31

shnir писал(а):
2018.03.03, 20:42
попробуйте вот так:

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

                <?= $form->field($model, 'catalog[]')->widget(Select2::classname(), [
если не получится, тогда покажите как к вам приходят данные в POST
POST:

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

Array
(
    [_csrf-frontend] => R5Yd9Vw0q4zKqjDmLihvN5Ps_hoKKsrCGVM3c3H8hAYg-07DNWHl7fPnc615Xz553p6JcH1n_YdNNV8aHbv8Pg==
    [Brigada] => Array
        (
            [name] => Gitis
            [persons] => 20
            [city] => 1
            [catalog] => Array
                (
                    [0] => 1
                    [1] => 4
                    [2] => 5
                )

            [image] => 
            [body] => dfffdffd
fdfff
fdfddffd
        )

    [file] => 
)
Если добавить квадратные скобки как вы говорите catalog[] то при редактировании не подставляются чекбоксы. Этот POST данных передан с просто catalog, без []

Wizard
Сообщения: 162
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

Re: yii2-save-relations-behavior и валидация

Сообщение Wizard » 2018.03.03, 23:59

webplus писал(а):
2018.03.03, 23:31
shnir писал(а):
2018.03.03, 20:42
попробуйте вот так:

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

                <?= $form->field($model, 'catalog[]')->widget(Select2::classname(), [
если не получится, тогда покажите как к вам приходят данные в POST
Если добавить квадратные скобки как вы говорите catalog[] то при редактировании не подставляются чекбоксы. Этот POST данных передан с просто catalog, без []

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

'options' => ['placeholder' => 'Выберите категорию ...', 'multiple' => true],
скорее всего сам выждет подставляет скобки, без скобок прилетело бы просто число а не массив

Wizard
Сообщения: 162
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

Re: yii2-save-relations-behavior и валидация

Сообщение Wizard » 2018.03.04, 00:22

попробуйте добавить

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

public function beforeValidate(): bool
{
    $this->catalog = array_filter((array)$this->catalog);
    return parent::beforeValidate();
}

andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: yii2-save-relations-behavior и валидация

Сообщение andku83 » 2018.03.04, 01:40

Судя по тому что делает ваше поведение, то в вашу модель данные даже не попадают.
А ошибка из-за того что category в данном случае является релейшен, внутри которого уже лежат модели, а не просто id.
И если это так то выше предложенный beforeValidate приведет к ошибке "свойство доступно только для чтения"

Wizard
Сообщения: 162
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

Re: yii2-save-relations-behavior и валидация

Сообщение Wizard » 2018.03.04, 13:17

webplus писал(а):
2018.03.03, 12:37
Здравствуйте!
Для сохранения связей использую поведение https://github.com/la-haute-societe/yii ... s-behavior
Все работает успешно.
Но я захотел проверить переданные данные из формы в модели

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

[['catalog'], 'each', 'rule' => ['exist', 'skipOnError' => true, 'targetClass' => Catalog::className(), 'targetAttribute' => 'id']]
или

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

[['catalog'], 'each', 'rule' => ['integer']],
Но выдает ошибку валидации: Значение «catalog» должно быть целым числом.

Если сделать print_r данных POST то там виден массив ключ => значение

в вьюхе:

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

                <?= $form->field($model, 'catalog')->widget(Select2::classname(), [
                    'data' => ArrayHelper::map(Catalog::find()->orderBy('sort ASC')->all(), 'id', 'name'),
                    'language' => 'ru',
                    'options' => ['placeholder' => 'Выберите категорию ...', 'multiple' => true],
                    'toggleAllSettings' => [
                        'selectLabel' => null,
                    ],
                    'pluginOptions' => [
                        'allowClear' => true
                    ],
                ]);?>
в модели

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

    public function getCatalog()
    {
        return $this->hasMany(Catalog::className(), ['id' => 'catalog_id'])->viaTable(UserCatalog::tableName(), ['user_id' => 'user_id']);
    }
Почему может не работать валидация?
а как ваша модель загружается в контроллере, связи точно сохраняются?

Wizard
Сообщения: 162
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

Re: yii2-save-relations-behavior и валидация

Сообщение Wizard » 2018.03.04, 15:37

webplus писал(а):
2018.03.03, 23:31
shnir писал(а):
2018.03.03, 20:42
попробуйте вот так:

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

                <?= $form->field($model, 'catalog[]')->widget(Select2::classname(), [
если не получится, тогда покажите как к вам приходят данные в POST
POST:

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

Array
(
    [_csrf-frontend] => R5Yd9Vw0q4zKqjDmLihvN5Ps_hoKKsrCGVM3c3H8hAYg-07DNWHl7fPnc615Xz553p6JcH1n_YdNNV8aHbv8Pg==
    [Brigada] => Array
        (
            [name] => Gitis
            [persons] => 20
            [city] => 1
            [catalog] => Array
                (
                    [0] => 1
                    [1] => 4
                    [2] => 5
                )

            [image] => 
            [body] => dfffdffd
fdfff
fdfddffd
        )

    [file] => 
)
Если добавить квадратные скобки как вы говорите catalog[] то при редактировании не подставляются чекбоксы. Этот POST данных передан с просто catalog, без []
согласно мануалу для загрузки связанных моделей надо использовать немного другой массив

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

/**
 * $_POST could be something like:
 * [
 *     'Company'     => [
 *         'name' => 'YiiSoft'
 *     ],
 *     'ProjectLink' => [
 *         [
 *             'language' => 'en',
 *             'name'     => 'yii',
 *             'link'     => 'http://www.yiiframework.com'
 *         ],
 *         [
 *             'language' => 'fr',
 *             'name'     => 'yii',
 *             'link'     => 'http://www.yiiframework.fr'
 *         ]
 *     ]
 * ];
 */
очевидно автор загружает как то иначе связи с POST

Аватара пользователя
webplus
Сообщения: 245
Зарегистрирован: 2012.02.24, 22:05
Контактная информация:

Re: yii2-save-relations-behavior и валидация

Сообщение webplus » 2018.03.04, 17:05

Wizard писал(а):
2018.03.04, 13:17
а как ваша модель загружается в контроллере, связи точно сохраняются?
вот так, все сохраняется, только валидация не работает

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

        $model = Brigada::findOne(Yii::$app->user->id);

        if($model->load(Yii::$app->request->post()) && $model->save())
        {
            Yii::$app->getSession()->setFlash('success', 'Ваш профиль успешно обновлен');
            return $this->refresh();
        }

        return $this->render('brigada', [
            'model' => $model,
        ]);

Wizard
Сообщения: 162
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

Re: yii2-save-relations-behavior и валидация

Сообщение Wizard » 2018.03.04, 17:15

webplus писал(а):
2018.03.04, 17:05
Wizard писал(а):
2018.03.04, 13:17
а как ваша модель загружается в контроллере, связи точно сохраняются?
вот так, все сохраняется, только валидация не работает

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

        $model = Brigada::findOne(Yii::$app->user->id);

        if($model->load(Yii::$app->request->post()) && $model->save())
        {
            Yii::$app->getSession()->setFlash('success', 'Ваш профиль успешно обновлен');
            return $this->refresh();
        }

        return $this->render('brigada', [
            'model' => $model,
        ]);
ошибка валидации заключается в том что вы валидируете объект как int
Последний раз редактировалось Wizard 2018.03.04, 17:50, всего редактировалось 1 раз.

Wizard
Сообщения: 162
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

Re: yii2-save-relations-behavior и валидация

Сообщение Wizard » 2018.03.04, 17:47

Собственно ни каких прави прописывать и не надо - в catalog у вас попадают иды это ключи объектов тем самым автоматом загружаете модели каталогов, если такого объекта нет то ничего не запишется.

в правилах оставьте

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

[['catalogs'], 'safe'],
если все же хочется сделать валидацию (в чем собственно скорее всего нет потребности в этом случае) для ид-ов то скорее всего надо создать форму

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

class CatalogForm extends Model
{
    public $catalog_id;

    public function rules()
    {
        return [
           [['catalog_id'], 'each', 'rule' => ['integer']],
        ];
    }

    public function beforeValidate(): bool
    {
        $this->catalog_id = array_filter((array)$this->catalog_id);
        return parent::beforeValidate();
    }
}

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

<?= $form->field($catalogsForm, 'catalog_id')->checkboxList($catalogs) ?>
полученные иды загружаем в модель

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

public function actionUpdate($id)
{
    $model = $this->findModel($id);

    $catalogsForm = new CatalogForm;
    $catalogsForm->catalog_id = ArrayHelper::getColumn($model->brigataCatalogs, 'catalog_id');

    $valid = true;
    if ($model->load(Yii::$app->request->post()) && $valid = $model->validate()) {
        if($catalogsForm->load(Yii::$app->request->post()) && ($valid = ($catalogsForm->validate() && $valid))) {
            $model->catalogs = ArrayHelper::getValue($catalogsForm->attributes, 'catalog_id');
        }
        if($valid && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        }
    }

    return $this->render('update', [
        'model' => $model,
        'catalogsForm' => $catalogsForm
    ]);
}

Ответить