Yii2:在使用事务的try-catch时显示用户友好的验证错误

Yii2:在使用事务的try-catch时显示用户友好的验证错误,yii,yii2,yii2-advanced-app,yii-extensions,Yii,Yii2,Yii2 Advanced App,Yii Extensions,我正在使用引导ActiveForm。这是我的表格: use yii\helpers\Html; use yii\bootstrap\ActiveForm; use kartik\file\FileInput; /* @var $this yii\web\View */ /* @var $model common\models\Customer */ /* @var $form yii\widgets\ActiveForm */ ?> <?php $form = ActiveForm

我正在使用引导
ActiveForm
。这是我的表格:

use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use kartik\file\FileInput;

/* @var $this yii\web\View */
/* @var $model common\models\Customer */
/* @var $form yii\widgets\ActiveForm */
?>
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data'],
    'id' => 'customer-form',
    'enableClientValidation' => true,
    'options' => [
        'validateOnSubmit' => true,
        'class' => 'form'
    ],
    'layout' => 'horizontal',
    'fieldConfig' => [
      'horizontalCssClasses' => [
          'label' => 'col-sm-4',
         // 'offset' => 'col-sm-offset-2',
          'wrapper' => 'col-sm-8',
      ],
    ],
]); ?>
<?= $form->field($model, 'email')->textInput(['maxlength' => true]) ?>
<?php ActiveForm::end(); ?>
这是控制器

现在规则中使用了必需的属性working。它不允许表单提交,直到必填字段中填充了一些值,但同时使用的唯一属性与目标类不起作用,并允许表单提交。单击提交表单后,表单将不会提交,但不会显示唯一验证错误。考虑到我在引导模式下使用表单,我希望表单在提交前显示唯一的提交错误,与要求的工作相同。我可以使用jqueryonblur函数来实现这一点,并发送定制的AJAX请求,但我想要yii2的默认解决方案

编辑
这是由于未保存用户而引发错误的地方

public static function customeruser( $model ) {
    $user = new User();
    $user->username = $model->email;
    $user->email = $model->email;
    $user->setPassword ( $model->legacy_customer_id );
    $user->generateAuthKey ();
    if ( !$user->save () ) {
        var_dump ( $user->getErrors () );
        exit ();
    } return $user->save () ? $user : null;
}
var\u dump()
显示以下内容

“用户名”=>数组(大小=1) 0=>字符串“此用户名已被使用”。(长度=37) 'email'=>array(size=1)0=>string'此电子邮件地址已被占用。'(length=42)


有两件事,三件事:

1。您不接受用户输入的电子邮件地址

2.如果在数据库中您的字段被视为NULL,它将插入一个空白条目

3.在第二次插入中,如果db字段不是NUll,它将向您显示错误消息

解决方案: 1.使数据库字段不为空

2.将电子邮件作为用户输入

3.尝试打印错误

if ($model->validate()) {
    // all inputs are valid
} else {
    // validation failed: $errors is an array containing error messages
    $errors = $model->errors;
}
4.删除
'skipOnError'=>为真,

试试上面的方法我相信你会得到解决方案


当您在事务中使用try-catch块时,您应该抛出并捕获异常等错误,以便回滚事务,并向用户显示消息

您没有在事务中使用或使用
try{}catch(){}
块的优点。如果未保存任何模型,并且catch块将回滚事务,则应始终引发
异常

例如,通过调用

$user_create = \common\models\User::customeruser($model);
然后返回
user
对象或
null
,否则,在下一行中,您将验证用户是否已创建

if ($user_create) {
如果模型未保存,只需从函数
customeruser()
中抛出异常,否则返回
$user
对象,您不必再次检查
$user\u create
以验证是否未保存用户,将引发异常,并将控制权转移到
catch
块和
$user\u create=\common\models\user::customeruser($model)后面的行将永远不会被调用

当我有多个模型要保存并且使用事务块时,我通常使用以下方法

$transaction = Yii::$app->db->beginTransaction ();
try {
    if ( !$modelUser->save () ) {
        throw new \Exception ( implode ( "<br />" , \yii\helpers\ArrayHelper::getColumn ( $modelUser->errors , 0 , false ) ) );
    }
    if ( !$modelProfile->save () ) {
        throw new \Exception ( implode ( "<br />" , \yii\helpers\ArrayHelper::getColumn ( $modelProfile->errors , 0 , false ) ) );
    }
    $transaction->commit();
} catch ( \Exception $ex ) {
    $transaction->rollBack();
    Yii::$app->session->setFlash ( 'error' , $ex->getMessage () );
}

我的be这将帮助你@Muhammad Aslam Omer Bro我需要你的帮助..我尝试了很多技巧,但找不到解决方案。请出示控制器代码。@AmiteshKumar已更新代码问题可能与你的数据有关,因此问题可能与代码无关;我们需要查看数据,以实际帮助排除故障。另外,您认为哪一个唯一的验证规则被破坏了?
if ($user_create) {
$transaction = Yii::$app->db->beginTransaction ();
try {
    if ( !$modelUser->save () ) {
        throw new \Exception ( implode ( "<br />" , \yii\helpers\ArrayHelper::getColumn ( $modelUser->errors , 0 , false ) ) );
    }
    if ( !$modelProfile->save () ) {
        throw new \Exception ( implode ( "<br />" , \yii\helpers\ArrayHelper::getColumn ( $modelProfile->errors , 0 , false ) ) );
    }
    $transaction->commit();
} catch ( \Exception $ex ) {
    $transaction->rollBack();
    Yii::$app->session->setFlash ( 'error' , $ex->getMessage () );
}
public static function customeruser( $model ) {
    $user = new User();
    $user->username = $model->email;
    $user->email = $model->email;
    $user->setPassword ( $model->legacy_customer_id );
    $user->generateAuthKey ();
    if(!$user->save()){
        throw new \Exception ( implode ( "<br />" , \yii\helpers\ArrayHelper::getColumn ( $user->errors , 0 , false ) ) );
    }
    return $user;
}
public function actionCreate() {
    $model = new Customer();
    if ( $model->load ( Yii::$app->request->post () ) ) {
        $transaction = Yii::$app->db->beginTransaction ();
        try {
            $user_create = \common\models\User::customeruser ( $model );
            $model->user_id = $user_create->id;
            $auth = \Yii::$app->authManager;
            $role = $auth->getRole ( 'customer' );
            $auth->assign ( $role , $model->user_id );

            if ( !$model->save () ) {
                throw new \Exception ( implode ( "<br />" , \yii\helpers\ArrayHelper::getColumn ( $model->errors , 0 , false ) ) );
            }

            $photo = UploadedFile::getInstances ( $model , 'uploads' );
            if ( $photo !== null ) {
                $save_images = \common\models\CustomerDocuments::save_document ( $model->user_id , $photo );
            }

            $transaction->commit ();
            return $this->redirect ( [ 'view' , 'id' => $model->user_id ] );
        } catch ( \Exception $ex ) {
            Yii::$app->session->setFlash ( 'error' , $ex->getMessage () );
            $transaction->rollBack ();
        }
    }

    if ( Yii::$app->request->isAjax ) {
        return $this->renderAjax ( 'create' , [
                    'model' => $model ,
                ] );
    }

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