Rahman
Rahman

Reputation: 452

How to create a form for insert and update action for related model in Yii2?

I have two models: S, Sp. In the Sp model, there is a hasOne() relation with S.

In the SpController I have two actions, insert and update, as follow:

public function actionCreate()
{
    $model = new Sp();

    if ($model->load(Yii::$app->request->post()) && $model->save()) {
        return $this->redirect(['view', 'id' => $model->id]);
    }

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

and

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

    if ($model->load(Yii::$app->request->post()) && $model->save()) {
        return $this->redirect(['view', 'id' => $model->id]);
    }

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

In the sp/views/_form.php I have a field that related to S, like this:

<?= $form->field($model->s, 'name')->textInput(['maxlength' => true]) ?>

It works fine in update action because of relation, but it throws an error which not exist s on <?= $form->field($model->s, 'name')->textInput(['maxlength' => true]) ?> in create action.

How to bind name field in the create action?

Upvotes: 0

Views: 1239

Answers (2)

rob006
rob006

Reputation: 22144

If you want to use model from relation in this way, you need to manually create it. Don't forget to actually save data from S model.

public function actionCreate() {
    $model = new Sp();
    $model->populateRelation('s', new S());

    if (
        $model->load(Yii::$app->request->post()) && $model->validate()
        && $model->s->load(Yii::$app->request->post()) && $model->s->validate()
    ) {
        $model->s->save();
        $model->s_id = $model->s->id;
        $model->save();
        return $this->redirect(['view', 'id' => $model->id]);
    }

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

But you should really consider creating dedicated form model instead of using Active Record directly. It will make view and controller much simpler.

Upvotes: 1

Dmytro Us
Dmytro Us

Reputation: 11

I think a proper way to achieve your goal is to create a FormModel having all the attributes you need (in this case 'name' of the S object), and use it in the view, something like:

$form->field($formModel, 'sName')->textInput(['maxlength' => true]) ?>

Upvotes: 1

Related Questions