【问题标题】:Yii2 update related model makes insertYii2更新相关模型制作插入
【发布时间】:2016-01-18 14:56:37
【问题描述】:

取决于这个问题:Yii2 updating two related models does not show data of the second。我已经将相关模型InvoiceItems 调用到它有很多关系的Invoices 模型。

但是,更新会导致在invoice_items 表中插入新记录,而不是将当前相关记录更新到invoices 表中。

我尝试在_form视图中添加每个InvoiceItems记录的id字段来解决这个问题,但它仍然存在。

以下是actionUpdate中的InvoicesController

public function actionUpdate($id)
    {
        $model = $this->findModel($id);
        //$invoiceItems = new InvoiceItems();

        $count = count(Yii::$app->request->post('InvoiceItems', []));
        //Send at least one model to the form
        $invoiceItems = [new InvoiceItems()];

        //Create an array of the products submitted
        for($i = 1; $i < $count; $i++) {
            $invoiceItems[] = new InvoiceItems();
        }


        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            //$invoiceItems->invoice_id = $model->id;
            if (Model::loadMultiple($invoiceItems, Yii::$app->request->post())){
              foreach ($invoiceItems as $item){
                $item->invoice_id = $model->id;
                //$item->id = $model->invoiceItems->id;
                $item->save(false);
              }

              return $this->redirect(['view', 'id' => $model->id]);
            }
            else{
               return var_dump($invoiceItems);
            }
        } else {
          //$invoiceItems->invoice_id = $model->id;
          $invoiceItems = $this->findInvoiceItemsModel($model->id);
            return $this->render('update', [
                'model' => $model,
                'invoiceItems' => $invoiceItems,
            ]);
        }
    }

这是_form的代码InvoicesController的视图:

<div class="invoices-form">

    <?php $form = ActiveForm::begin(); ?>

    <?= $form->field($model, 'created')->textInput() ?>

    <?= $form->field($model, 'type')->textInput(['maxlength' => true]) ?>
  <hr />
  <?php if (is_array($invoiceItems)): ?>
  <?php foreach ($invoiceItems as $i => $item): ?>
  <?= $form->field($item, "[$i]id")->textInput();?>
    <?= $form->field($item, "[$i]item_id")->textInput();?>
    <?= $form->field($item, "[$i]unit_id")->textInput();?>
    <?= $form->field($item, "[$i]qty")->textInput();?>
  <?php  endforeach; ?>
  <?php  else: ?>
    <?= $form->field($invoiceItems, "item_id")->textInput();?>
    <?= $form->field($invoiceItems, "unit_id")->textInput();?>
    <?= $form->field($invoiceItems, "qty")->textInput();?>
  <?php endif; ?>    

    <div class="form-group">
        <?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
    </div>

    <?php ActiveForm::end(); ?>

</div>

以下屏幕截图直观地展示了我所得到的:

【问题讨论】:

    标签: activerecord yii2


    【解决方案1】:

    如果你在更新中不需要新记录,你应该删除

    这部分

        $count = count(Yii::$app->request->post('InvoiceItems', []));
        //Send at least one model to the form
        $invoiceItems = [new InvoiceItems()];
    
        //Create an array of the products submitted
        for($i = 1; $i < $count; $i++) {
            $invoiceItems[] = new InvoiceItems();
        }
    

    您以这种方式创建的 $invoiceItems 显然是"new",然后被插入..对于更新,模型必须不是新的.. 你已经有相关的模型来保存它们来自 post.. 和 load multiple

    如果您需要管理新模型(例如:因为您在宽格式更新操作中添加了新记录),您可以测试

    $yourModel->isNewRecord
    

    如果这是新检查,那么如果用户已正确设置相关字段,您可以将其保存

    $yourModel->save(); 
    

    否则你可以简单的discart..(不保存它)

    【讨论】:

    • 请看我的回答,取决于你的回答。
    • 我已经更新了 asnwer 并提出了一些新记录的建议
    【解决方案2】:

    我很确定下面的这段代码当然会用提交的数据填充一个名为 $invoiceItems 的数组。

    if (Model::loadMultiple($invoiceItems, Yii::$app->request->post())){
          foreach ($invoiceItems as $item){
            $item->invoice_id = $model->id;
            //$item->id = $model->invoiceItems->id;
            $item->save(false);
          }
    }
    

    但是所有 $items 都有“插入”场景(可能是您允许设置属性“ID”,但通常这在 Gii 生成的代码中是不允许的。然后你会得到“新项目”每当你保存。

    如果您在 loadMultiple 之后添加 return var_dump($invoiceItems);,您将看到只有 safe 属性填充了提交的数据。

    您也没有在保存之前验证它们,这也有点糟糕。

     if (Model::loadMultiple($invoiceItems, Yii::$app->request->post()) && Model::validateMultiple($invoiceItems)) {
    

    http://www.yiiframework.com/doc-2.0/guide-input-tabular-input.html

    【讨论】:

      【解决方案3】:

      根据scaisEdge 的回答和this widget documentation。我可以确定问题的解决方案。

      简单地说,在我的代码中我忽略了两个模型之间的关系,当我说:

      $count = count(Yii::$app->request->post('InvoiceItems', []));
              //Send at least one model to the form
              $invoiceItems = [new InvoiceItems()];
      

      $invoiceItems 的值应使用如下关系获得:

      $invoiceItems = $model->invoiceItems;
      

      但是,在更新期间向相关模型InvoiceItems 添加新记录时,我还有另一个问题。

      【讨论】:

      • 添加新记录有点复杂,因为在视图中请求添加 InvoceItems .. 但在视图中通常不执行操作.. 您可以直接在视图中执行 (不是面向 MVC 的),或者您可以通过 ajax 调用服务操作来获取所需的新模型。
      • 我认为最后一个错误可能会有所帮助。即我只是加载预定义的InvoiceItems 进行更新,然后为新记录创建新的InvoiceItems 模型。这是如何在视图中创建新的插入字段以及如何在控制器中加载它们的问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多