web-dev-qa-db-ja.com

Yii2複数のモデルを1つの形式で

Yii2で複数のモデルを1つのフォームで使用するにはどうすればよいですか?

私の場合: - ER diagram

作成アクションでは、agenda_fiscalizacaoテーブルに保存できますが、更新時にフォームを読み込もうとすると、次のエラーが発生します。

Call to a member function formName() on array    

私の更新アクション:

public function actionUpdate($id)
{
    $model = $this->findModel($id);
    $modelAgenda = AgendaFiscalizacao::findAll(['fiscalizacao_id' => $id]);

    if ($model->load(Yii::$app->request->post()) && Model::loadMultiple($modelAgenda, Yii::$app->request->post())) {
        $valid = $model->validate();
        $valid = $modelAgenda->validade() && $valid;

        if ($valid) {
            $model->save(false);
            $modelAgenda->save(false);
            return $this->redirect(['view', 'id' => $model->id]);
        }
    }

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

私のフォームビュー

<?= $form->field($modelAgenda, 'agenda_id')->checkboxList(Agenda::combo(), ['class' => 'checkbox']) ?>
<?= $form->field($model, 'bioma_id')->dropDownList(Bioma::combo(), ['Prompt' => $Prompt]) ?>
<?= $form->field($model, 'nome')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'tipo_doc')->radioList(['CPF'=>'CPF', 'CNPJ'=>'CNPJ'], ['class' => 'radio']) ?>
<?= $form->field($model, 'n_doc')->widget(MaskedInput::className(), ['mask' => ['999.999.999-99', '99.999.999/9999-99']]) ?>
<?= $form->field($model, 'observacao')->textarea(['rows' => 7]) ?>    

何が悪いのでしょうか?

編集(完全エラー):

enter image description here

7
jflizandro

1)同じタイプの複数のモデルを操作する場合、エラーは次の行にあります。

_$valid = $modelAgenda->validade() && $valid;
_

まず、$modelAgenda->validate()である必要があり、2番目の_$modelAgenda_にはモデルの配列が含まれ、validate()メソッドは単一のモデルでのみ呼び出すことができます。

複数のモデルを検証するために、Yii2は組み込みメソッドvalidateMultiple()の使用を提案しています。

_use yii\base\Model;

...

$valid = Model::validateMultiple($modelAgenda) && $valid;
_

複数のモデルでの作業については、公式ドキュメントで詳しく説明されています( 表形式の入力の収集 )。

次のように、モデル配列にidでインデックスを付けることをお勧めします。

_$models = YourModel::find()->index('id')->all();
_

2)異なるタイプのモデルが2つだけ必要な場合は、findAll()を使用しないでください。これは、複数のモデルを検索するためのものであり、常に配列(空の結果でも)。モデルを初期化するには、newアクションにはcreateを使用し、updateアクションにはfindOne()を使用します。 _$firstModel_と_$secondModel_の2つのモデルを初期化したとすると、次のようにロードして保存できます。

_$isSuccess = false;

Yii::$app->db->transaction(function () use ($isSuccess) {
    $areLoaded = $firstModel->load(Yii::$app->request->post()) && $secondModel->load(Yii::$app->request->post();
    $areSaved = $firstModel->save() && $secondModel->save();
    $isSuccess = $areLoaded && $areSaved;
});

if ($isSuccess) {
    return $this->redirect(['view', 'id' => $model->id]);
}
_

2番目のモデルの保存が失敗した場合にトランザクションが追加されます(したがって、最初のモデルも保存されません)。

または、モデル内で transactions を宣言することもできます。次に例を示します。

_return [
    'admin' => self::OP_INSERT,
    'api' => self::OP_INSERT | self::OP_UPDATE | self::OP_DELETE,
    // the above is equivalent to the following:
    // 'api' => self::OP_ALL,
];
_

次に、以下を使用します。

_$firstModel->scenario = 'scenarioForTransaction';
$secondModel->scenario = 'scenarioForTransaction';
$areLoaded = $firstModel->load(Yii::$app->request->post()) && $secondModel->load(Yii::$app->request->post();
$areSaved = $firstModel->save() && $secondModel->save();

if ($areLoaded && $areSaved) {
    return $this->redirect(['view', 'id' => $model->id]);
}
_

3つ以上のモデルの場合は、ループを使用することをお勧めします。

P.S。異なるコントローラー/アクションへの保存を分離し、AJAX経由で呼び出すことをお勧めします。よりユーザーフレンドリーになります。

関係を保存するには、- 関係の保存 をお読みください。

8
arogachev
public function actionUpdate($id)
{
    $model = $this->findModel($id);
    $modelAgenda = AgendaFiscalizacao::findAll(['fiscalizacao_id' => $id]);

    if ($model->load(Yii::$app->request->post()) && $modelAgenda->load(Yii::$app->request->post()) && Model::validateMultiple([$model, $modelAgenda])) {

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

    }

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

たとえば、次のリンクを参照できます: http://blog.dedikisme.com/blog/2014/10/13/yii2-building-a-single-form-with-multiple-models

3
Dedy Kurniawan

更新ファイルでrenderを使用しているときに、$ modelAgendaをview/update.phpからview/_form.phpファイルにレンダリングしていません。

0
Lakhan Singh