我如何跳过 Yii2 中的唯一字段?

How can i skip unique field in 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,
    ]
]); ?>

您的验证完全不正确。您在规则中使用 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'],

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

好吧...我将下面的代码剪切到每个操作:create/update。

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

然后从表单组件中删除 validationUrl。在模型内部我制定了这个规则 [['course_order'],'unique']... 工作正常...