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

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

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

Сообщение webplus »

Здравствуйте!
Для сохранения связей использую поведение 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']);
    }
Почему может не работать валидация?
Сайт по работе в Украине: https://jobis.com.ua/. Сайт по поиску строителей: https://stroyzakaz.com.ua/
Создание сайтов в Киеве: https://webplus.com.ua/ по доступной цене.
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

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

Сообщение andku83 »

как выглядит ваша форма когда у вашего Юзера есть несколько каталогов?
Аватара пользователя
webplus
Сообщения: 336
Зарегистрирован: 2012.02.24, 22:05

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

Сообщение webplus »

shnir писал(а): 2018.03.03, 17:26 как выглядит ваша форма когда у вашего Юзера есть несколько каталогов?
вот так http://joxi.ru/VrwzRWvCKn998A
Сайт по работе в Украине: https://jobis.com.ua/. Сайт по поиску строителей: https://stroyzakaz.com.ua/
Создание сайтов в Киеве: https://webplus.com.ua/ по доступной цене.
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

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

Сообщение andku83 »

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

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

                <?= $form->field($model, 'catalog[]')->widget(Select2::classname(), [
если не получится, тогда покажите как к вам приходят данные в POST
Аватара пользователя
webplus
Сообщения: 336
Зарегистрирован: 2012.02.24, 22:05

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

Сообщение webplus »

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, без []
Сайт по работе в Украине: https://jobis.com.ua/. Сайт по поиску строителей: https://stroyzakaz.com.ua/
Создание сайтов в Киеве: https://webplus.com.ua/ по доступной цене.
BalykhinAS
Сообщения: 179
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

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

Сообщение BalykhinAS »

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],
скорее всего сам выждет подставляет скобки, без скобок прилетело бы просто число а не массив
BalykhinAS
Сообщения: 179
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

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

Сообщение BalykhinAS »

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

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

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 »

Судя по тому что делает ваше поведение, то в вашу модель данные даже не попадают.
А ошибка из-за того что category в данном случае является релейшен, внутри которого уже лежат модели, а не просто id.
И если это так то выше предложенный beforeValidate приведет к ошибке "свойство доступно только для чтения"
BalykhinAS
Сообщения: 179
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

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

Сообщение BalykhinAS »

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']);
    }
Почему может не работать валидация?
а как ваша модель загружается в контроллере, связи точно сохраняются?
BalykhinAS
Сообщения: 179
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

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

Сообщение BalykhinAS »

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
Сообщения: 336
Зарегистрирован: 2012.02.24, 22:05

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

Сообщение webplus »

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,
        ]);
Сайт по работе в Украине: https://jobis.com.ua/. Сайт по поиску строителей: https://stroyzakaz.com.ua/
Создание сайтов в Киеве: https://webplus.com.ua/ по доступной цене.
BalykhinAS
Сообщения: 179
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

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

Сообщение BalykhinAS »

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
Последний раз редактировалось BalykhinAS 2018.03.04, 17:50, всего редактировалось 1 раз.
BalykhinAS
Сообщения: 179
Зарегистрирован: 2018.02.05, 13:41
Контактная информация:

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

Сообщение BalykhinAS »

Собственно ни каких прави прописывать и не надо - в 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
    ]);
}
Ответить