Yii没有验证超过2列的唯一索引


Yii not validating unique index over 2 columns

我在数据库的两列中添加了一个唯一键;

ALTER TABLE `foo`
  ADD UNIQUE KEY `foo_uk` (`field1`, `field2`);

这是正确的,如果我试图添加一行,其中这两个字段的值已经存在于另一行中,则会出现完整性约束冲突。

然而,我无法让Yii拿起束缚。

在我的模型中,我添加了一条规则;

public function rules()
{
    return array(
        ...
        array('field1', 'unique', 'criteria'=>array(
            'condition'=>'`field2`=:field2',
            'params'=>array(
                ':field2'=>$this->field2
            )
        ),
        ...
    );
}

当我保存模型时,我可以看到这个规则正在运行,并且在验证期间执行以下查询:

SELECT 1 FROM `foo` `t` WHERE (`field2`=:field2) AND (`t`.`field1`=:ycp0) LIMIT 1

我在mysql中运行这个命令进行了检查,它返回了正确的结果。当表为空时,它返回0个集合,当我尝试添加相同的行时,它会返回1

然而,由于某种原因,它并没有触发验证失败,而是抛出了CDbException:

CDbCommand failed to execute the SQL statement: SQLSTATE[23000]: Integrity
constraint violation: 1062 Duplicate entry 'field1TestData-field2TestData' for
key 'foo_uk'. The SQL statement executed was: INSERT INTO `foo` (`field1`,
`field2`...etc) VALUES (:yp0, :yp1...etc)

我希望在保存发生之前的验证能够优雅地抛出错误,并将我带回到带有正确错误消息的表单('field1' and 'field2' must be unique或其他形式)?

关于这里发生的事情,请有人给我指一个正确的方向。我需要创建自己的验证方法吗?我在这里假设Yii应该像处理模型的规则方法中那样处理验证错误?

也许这个扩展将帮助您:唯一属性验证器

从扩展页面:

Yii提供了一桶验证器,其中包括一个唯一验证器,用于验证属性值在相应的数据库表中是否唯一。但是,如果数据库唯一约束包含多个属性,该怎么办?

这就是我在项目中使用的内容。

这是一个的例子

public function rules() {
    return array(
        array('firstKey', 'UniqueAttributesValidator', 'with'=>'secondKey'),
    );
}