YiiHaa Webdevelopment blog about Yii-framework and more

17Feb/1211

Validate unique constraints with more then one attribute

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?

I have seen a couple Yii extensions which solve the problem but none of them are using the built-in CUniqueValidator parts. There are two ways to solve the validation problem, the first one is to add some criteria to the unique validator:

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

That will do the trick, however it can get a bit cleaner. The UniqueAttributesValidator does this for you:

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

The UniqueAttributesValidator uses parts of CUniqueValidator and extends it by adding certain criteria. It also works for unique constraints with N attributes:

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

Download the UniqueAttributesValidator HERE.

Posted by martijn

Comments (11) Trackbacks (0)
  1. “more thEn” ?

  2. Der UniqueAttributesValidator funktioniert sehr gut. Der Code sieht auch sauber aus.

    Allerdings musst du das Beispiel oben nochmal überarbeiten:
    * Der Zugriff auf die Model-Eigenschaften ist mit $this nicht möglich, da der Wert noch nicht gesetzt ist.
    * Der Zugriff funktionierte bei mir aber so $_POST['Model']['secondKey']

    Da diese Schreibweise nicht sehr schön ist bevorzuge ich auch deinen Validator.

    Dankeschön

  3. The UniqueAttributesValidator works very well. The code looks clean.

    However, you have the example revise up again:
    * Access to the model properties using $ this is not possible, because the value is not yet set.
    * Access work for me but that $ _POST ['Model'] ['secondkey']

    Since this notation is not very nice I prefer your validator.

    thank-you

  4. Nice and clean solution, but I suggest changing line 27 to:

    $conditionParams[] = $object->getTableAlias(true) . ‘.’ . “`{$attribute}`=:{$attribute}”;

    Otherwise you’re bound to get errors if the model has any eager relations (“with”) set in the default scope.

  5. Hi,

    Thanks for this simple and great extension! I noticed a bug, I’m using SQL Server instead of MySQL and notation of columns with `COLUMN NAME` is not supported on SQL Server and raises exception. It would work in both databases simply removing character ` from code, so it would be:

    Replace:
    $conditionParams[] = “`{$attribute}`=:{$attribute}”;
    with:
    $conditionParams[] = “{$attribute}=:{$attribute}”;

    Thanks!

  6. Absoluter netter Blog. Werde jetzt öfter reinschauen Vielen Dank und Grüsse aus Köln

  7. Great piece of code. Thanks!

  8. How to install this? I downloaded it, unzipped it in “extensions” folder and added the file path in “components” in config/main.php but can not make it to work.

  9. Problem with Gii
    Hey, im getting this exception when i try to use Gii – models,

    UniqueAttributesValidator and its behaviors do not have a method or closure named “init”.

  10. Hai thanks for the good extension, but it is not working for me.,please tell me where to install your extension.,now am installed it on \protected\extension\
    and using it like the following lines,
    array(‘categoryName’,'ext.Validators.UniqueAttributesValidator’,'with’=>’appId’),

  11. Great code! Thanks.


Leave a comment

No trackbacks yet.