使用表单复杂yii2保存表单更新时出现的问题

时间:2016-11-01 10:32:27

标签: php forms yii yii2 yii2-basic-app

我有三个表,即家庭(PK id_family和FK id_husband),丈夫(PK id_husband)和house(PK id_husband)。因为丈夫与房子有关。然后桌子的丈夫与家庭桌子有关。

我已经制作了一个更新表格来形成房子以查看下面的参考资料。在我在表格中更新逻辑之前,表格中的字段将更新丈夫,在平均字段即'status_husband'。因为它已成功地做到了。 然后,当进程保存在actionUpdate中时,在更新表单上的输入时,将自动加载到族表中的字段。 Fieldnya id_family,id_husband和status_family。因为它管理得很好,我使用了形式复杂的概念。

我想在更新中并且将完成所有这一切的过程时,有验证要求表单中的所有字段更新所有“省”和“城市”必须用值'example1填充'全部。因此,如果不处理一个差异。也许有人可以帮助我,谢谢

表单更新中的代码视图..

<?php

use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use yii\widgets\Pjax;
use yii\bootstrap\Modal;
use yii\helpers\Url;
use yii\db\ActiveRecord;
use yii\helpers\ArrayHelper;
use app\models\Husband;
use kartik\widgets\Select2;

?>

<h1 align="center">Form Ubah House</h2>
<?php
echo "&nbsp";
echo "&nbsp";
?>

<?php $form = ActiveForm::begin([
    'layout' => 'horizontal', 
    'enableAjaxValidation' => false,
    'id' => 'update-form',
    ]); 
?>

<?php 
    $data = ArrayHelper::map(Husband::find()->all(), 'id_husband', 'name_husband'); 

    echo $form->field($house, 'id_husband')->widget(Select2::classname(), [
    'data' => $data,
    'model' => $house,
    'language' => 'id',
    'disabled' => true,
    'options' => ['placeholder' => 'Choose..'],
    'pluginOptions' => [
        'allowClear' => false,
        'width' => '300px',
        ],
    ])->label('Name husband');
?>


<?php 
echo $form->field($house, 'province')->widget(Select2::classname(), [
    'model' => $house,
    'hideSearch' => true,
    'data' => ['example1' => "Example1", 'example2' => "Example2"],
    'language' => 'id',
    'options' => [
        'placeholder' => 'Choose..',
        'id' => 'province',
    ],
    'pluginOptions' => [
        'allowClear' => false,
        'width' => '380px',
        ],
    ])->label('Province'); 
?>  

<?php 
echo $form->field($house, 'city')->widget(Select2::classname(), [
    'model' => $house,
    'hideSearch' => true,
    'data' => ['example1' => "Example1", 'example2' => "Example2"],
    'language' => 'id',
    'disabled' => true,
    'options' => [
        'placeholder' => 'Choose..',
        'id' => 'city',
    ],
    'pluginOptions' => [
        'allowClear' => false,
        'width' => '380px',
        ],
    ])->label('City'); 
?>

<?= $form->field($family, 'id_family')->hiddenInput(['readOnly' => true, 'style' => 'width:100px'])->label(false); ?>

<?php
$family->id_husband = $house->id_husband;
?>
<?= $form->field($family, 'id_husband')->hiddenInput(['style' => 'width:100px'], ['disabled' => true])->label(false); ?>

<?= $form->field($family, 'status_house')->hiddenInput(['style' => 'width:380px', 'value'=>'Tetap'], ['disabled' => true])->label(false); ?>

<div class="form-group">
    <div class="col-sm-offset-4">

<?= Html::submitButton('Edit', ['class' => 'btn btn-primary']) ?>

<?php
echo "&nbsp";
echo "&nbsp"; 
echo Html::a('Exit', ['index'],[
    'class'=>'btn btn-success',
    'onclick' =>'$("#houseModal").modal("hide");
    return false;'
    ]);
?>

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

HouseController中的代码actionUpdate

public function actionUpdate($id)
    {
        $house = House::findOne($id);
        if (!$house) {
            throw new NotFoundHttpException("The house was not found.");
        }

        $family = new Family();
        if (!$family) {
            throw new NotFoundHttpException("The family was not found.");
        }

        if ($house->load(Yii::$app->request->post()) && $family->load(Yii::$app->request->post())) {
            $isValid = $house->validate();
            $isValid = $family->validate() && $isValid;
            if ($isValid) {

                // Code for update field status_husband in table Husband
                $husband = Husband::findOne($id);
                $husband->status_husband = 'Meninggal';
                $husband->save();

                // Code for update field in table house
                $house->save(false);

                // Code for insert in table family
                $family->save(false);

                Yii::$app->session->setFlash('success', 'Success!');
                return $this->redirect(['index']);
                return $this->refresh();
            }
        } else {
            if (Yii::$app->request->isAjax) {
                return $this->renderAjax('update', [
                    'house' => $house,
                    'family' => $family]);
            } else {
                return $this->render('update', [
                    'house' => $house,
                    'family' => $family]);
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

如果使用相同的数据库连接组件将所有3个模型保存到同一个数据库,则可以使用数据库事务:

public function actionUpdate($id)
{
    $house = House::findOne($id);
    if (!$house) {
        throw new NotFoundHttpException("The house was not found.");
    }

    $family = new Family();
    if (!$family) {
        throw new NotFoundHttpException("The family was not found.");
    }

    $husband = Husband::findOne($id); // Why use the same $id that you use to find $house?
    if (!$husband) {
        throw new NotFoundHttpException("The husband was not found.");
    }

    $post = Yii::$app->request->post();

    // we get the database component used by the House model class and begin a transaction
    $transaction = House::getDb()->beginTransaction();

    try {
        if ($house->load($post) && $family->load($post)) {

            // Try to save $house model
            if(!$house->save()) {
                // If we get a validation error then we will throw an exception and execute the code in catch
                throw new \Exception('House Validation Error');
            }

            // Try to save $family model
            if(!$family->save()) {
                // If we get a validation error then we will throw an exception and execute the code in catch
                throw new \Exception('Family Validation Error');
            }

            // Set new status for $husband
            $husband->status_husband = 'Meninggal';

            // Try to save $husband model
            if(!$husband->save()) {
                // If we get a validation error then we will throw an exception and execute the code in catch
                throw new \Exception('Husband Validation Error');
            }

            // we commit the database changes after every model has been saved succesfully
            $transaction->commit();

            Yii::$app->session->setFlash('success', 'Success!');
            return $this->redirect(['index']);

            // This doesn't get called ever, so why have it here?
            // return $this->refresh();
        } else {
            throw new \Exception('Load Error');
        }
    } catch(\Exception $e) {
        // If we catch any exception we rollback the transaction, reverting all the changes made during the transaction
        $transaction->rollback();
    }

    if (Yii::$app->request->isAjax) {
        return $this->renderAjax('update', [
            'house' => $house,
            'family' => $family]);
    } else {
        return $this->render('update', [
            'house' => $house,
            'family' => $family]);
    }
}