YiiHaa Webdevelopment blog about Yii-framework and more

17Feb/127

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 (7) 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!


Leave a comment

No trackbacks yet.