首页 > 解决方案 > 如何跳过 Yii2 中的唯一字段?

问题描述

我有一个独特的字段,我在编辑或添加新的培训课程时会检查它。但是,由于某种原因,当我在字段中输入值时,它不会向我显示该字段已被占用的提示。

另外,我需要这样做:当我更改值并且没有更改此唯一字段,而是保持原样时,验证器不应发誓该字段已被占用。

感谢。

InfCourses 模型:

public function rules()
{
    return [
        [['name', 'short_description', 'price', 'favorite', 'active', 'course_order', 'link'], 'required'],
        [['price', 'active'], 'integer'],
        [['favorite'], 'string'],
        [['name', 'short_description', 'link'], 'string', 'max' => 255],
        [['active'], 'exist', 'skipOnError' => true, 'targetClass' => InfStatuses::className(), 'targetAttribute' => ['active' => 'id']],
        [['course_order'], 'integer', 'min' => 1],
        [
            ['course_order'], 'unique', 
            'targetAttribute' => ['course_order'], 
            'filter' => ['!=', 'id', Yii::$app->request->get('id')],
        ],
    ];
}

InfCoursesController 中的验证器:

public function actionValidate()
{
    $model = new InfCourses();

    if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
        Yii::$app->response->format = Response::FORMAT_JSON;
        return ActiveForm::validate($model);
    }
}

部分表单代码:

<?php $form = ActiveForm::begin([
    'enableAjaxValidation' => true,
    'validationUrl' => 'validate',
    'options' => [
        'data-pjax' => true,
    ]
]); ?>

标签: ajaxactiverecordyii2pjax

解决方案


您的验证根本不正确。您正在使用Yii::$app->request->get('id')您的规则,这可能是您的问题的主要来源。模型不应直接访问请求或 Web 用户组件 - 它破坏了 MVC 模式。同样以这种方式将值直接放入规则中可能会给您带来意想不到的结果。您应该检查此验证器生成的查询,因为很难猜测这种扭曲的规则会发生什么。

但是更容易修复actionValidate()和区分验证新记录和验证现有记录:

public function actionValidate($id = null) {
    if (empty($id)) {
        $model = new InfCourses();
    } else {
        $model = $this->findModel($id);
    }

    if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
        Yii::$app->response->format = Response::FORMAT_JSON;
        return ActiveForm::validate($model);
    }
}

然后,您可以将您的独特规则限制为:

[['course_order'], 'unique'],

Validator 将足够聪明,可以检测到它正在验证现有记录,并且不会将未更改的字段值报告为重复项。您只需在此操作 URL 中提供记录 ID。


推荐阅读