如何在Yii2中跳过唯一字段?

时间:2018-10-27 11:18:58

标签: ajax activerecord yii2 pjax

我在编辑或添加新的培训课程时会检查一个唯一字段。但是,由于某种原因,当我在一个字段中输入一个值时,并没有提示我该字段已被使用。

此外,我需要执行以下操作:当我更改值并且没有更改此唯一字段时,而是按原样保留该字段,则验证者不应发誓该字段已被使用。

谢谢。

课程模式:

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,
    ]
]); ?>

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

好吧...我将以下代码剪切到每个动作上:创建/更新。

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'] ...工作正常...