@Gregpopov
Full stack web developer

Как в Yii2 сохранить множество many-to-one?

Привет. Итак:
1. Есть таблица Товар
2. Есть таблица Тех. характеристики

Вот модель тех. характеристик:
class ProductTechSpec extends \yii\db\ActiveRecord
{
    public static function tableName()
    {
        return 'product_tech_spec';
    }

    public function attributeLabels()
    {
        return [
            'id' => 'primary key',
            'product_id' => 'primary key',
            'title'      => 'заголовок',
            'spec'       => 'описание',
        ];
    }

    public function getProduct()
    {
        return $this->hasOne(Product::className(), ['id' => 'product_id']);
    }

    public static function find()
    {
        return new ProductTechSpecQuery(get_called_class());
    }
}


Вот что удалось собрать на просторах форумов:
public function actionCreate()
    {
        $model = ['product' => new Product(), 'product_tech_spec' => [new ProductTechSpec()]];

        $count = count(Yii::$app->request->post('Setting', []));

        for($i = 1; $i < $count; $i++) {
            $model['product_tech_spec'][] = new ProductTechSpec();
        }

        if ($model['product']->load(Yii::$app->request->post()) && $model['product']->save()) {

            if (Model::loadMultiple($model['product_tech_spec'], Yii::$app->request->post())){

                Model::validateMultiple($model['product_tech_spec'],true);

                foreach ($model['product_tech_spec'] as $tech_spec) {
                    $tech_spec->product_id = $model['product']->id;
                    $tech_spec->save(false);
                }

                return $this->redirect(['view', 'id' => $model['product']->id]);

            }else{
                return $this->render('create', [
                    'model' => $model,
                ]);
            }
        }else{
            return $this->render('create', [
                'model' => $model,
            ]);
        }
    }


Но, есть одно «но»:
Сохраняет только последнюю техническую характеристику, в чем ошибка?

P.S. Как проводить валидацию для сгенерированных во view полей отдельно для каждого? Для модели если заполнить одно поле, все остальные автоматически становятся валидны.
  • Вопрос задан
  • 183 просмотра
Пригласить эксперта
Ответы на вопрос 1
Demetriy
@Demetriy
веб и мобильная разработка
Я не очень понимаю, зачем вы в переменную $model засовываете массив с продуктом и его связанными моделями, в уроках вроде такому не учат, так же, рекомендую использовать транзакции, чтобы в случае возникновения где-то ошибок не сохранялось ничего и конечно же, вы зря отключаете валидацию при сохранении характеристик.

1) Сделайте
$model['product_tech_spec'] = [new ProductTechSpec()];
    for($i = 1; $i < $count; $i++) {
        $model['product_tech_spec'][] = new ProductTechSpec();
    }


вместо
for($i = 1; $i < $count; $i++) {
        $model['product_tech_spec'][] = new ProductTechSpec();
    }


2) Тут ошибка:
Model::validateMultiple($model['product_tech_spec'],true);


Второй аргумент надо убрать.

3) Так же от двух условий
return $this->render('create', [
                'model' => $model,
            ]);


Можно избавиться, просто удалив два else и вставив этот кусок кода в конце.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы