Question

I have added a unique key over two columns in my database;

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

This is working correctly, I get an integrity constraint violation if I attempt to add a row where the values of these two fields already exist in another row.

However, I can't get Yii to pick up the restraint.

In my model I've added a rule;

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

I can see this rule is running when I save the model and is performing the following query during validation:

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

I've checked by running this command in mysql and it's returning a correct result, When the table is empty, it returns 0 sets, and when I try to add an identical row, it's returning 1.

However, for some reason it's not triggering a fail on validation, instead it's throwing a 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)

I would expect the validation before the save occurs to throw an error gracefully and take me back to the form with the correct error message ('field1' and 'field2' must be unique or whatever it would be)?

Please could someone point me in the right direction as to what's going on here. Do I need to create my own validation method, I am assuming here that Yii should handle the validation error as it's in the rules method for the model?

Was it helpful?

Solution

May be this extension will help you : unique-attributes-validator

From the extension page:

Yii comes with bucket of validators including a unique validator which validates whether an attribute value is unique in the corresponding database table. But what if your database unique constraint contains more than one attribute?

This is what I'm using on my projects.

here's an example

public function rules() {
    return array(
        array('firstKey', 'UniqueAttributesValidator', 'with'=>'secondKey'),
    );
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top