2

In the rules() of my RegisterForm model:

[ 'user_username', 'unique', 'targetClass' => 'app\models\User', 'message' => 'This username is already been taken.' ],

In my controller:

$model = new RegisterForm();
if ( $model->load( Yii::$app->request->post() ) ) {
    if ( $user = $model->register() ) {
        return $this->redirect( [ '/login' ] );
    }
}

In RegisterForm:

public function register() {  
    $user = new User();
    $user->user_firstname = $this->user_firstname;
    $user->user_lastname = $this->user_lastname;
    $user->user_username = $this->user_username;
    $user->user_email = $this->user_email;
    $user->setPassword( $this->user_password );

    if ( !$user->validate() ) {
        return null;
    }    

    if ( $user->save() ) {
        return $user;   
    }

    return null;
}

Form:

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

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

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

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

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

<?= $form->field( $model, 'user_password' )->passwordInput() ?>

<?= $form->field( $model, 'user_password_repeat' )->passwordInput() ?>

<?= Html::submitButton( 'Register', [ 'class' => 'btn btn-primary', 'name' => 'register-button' ] ) ?>

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

Yet when I enter a username that I know already exists, the error never comes up and the record tries to save, though I get: Integrity constraint violation: 1062 Duplicate entry ...

EDIT: if I add the unique rule to the User model itself the form will not submit if I input a username that exists, the errors just don't show up

4

1 回答 1

3

就像我怀疑的那样,您没有user_username在客户端检查唯一属性。它不起作用的原因是您没有发送 Ajax 请求来检查数据库中的结果。与其他规则不同,unique规则需要向服务器发出额外的 Ajax 请求,因为如果 Javascript 会检索所有当前注册的用户名并将其存储在客户端的某个位置,那将是一件非常糟糕的事情。

为了解决你的问题,在表格中写下这样的内容:

$form = ActiveForm::begin([
    'enableAjaxValidation' => true,
    'validationUrl' => [<URL HERE>],
]);

现在您必须在控制器中创建一个方法(操作),将验证(不仅仅是唯一的,所有这些)返回到ActiveForm. 所以它可能是这样的:

public function actionAjaxValidation()
{
    $post = Yii::$app->request->post();
    $model = new YourClass();

    if (!$model->load($post)) {
        throw new HttpException(403, 'Cannot load model');
    }

    $array = ActiveForm::validate($model);

    return json_encode($array);
}
于 2016-12-18T07:41:25.573 回答