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.
June 13th, 2012 - 15:48
“more thEn” ?
August 29th, 2012 - 11:42
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
August 29th, 2012 - 11:46
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
October 29th, 2012 - 09:15
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.
March 12th, 2013 - 10:59
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!
April 29th, 2013 - 07:48
Absoluter netter Blog. Werde jetzt öfter reinschauen Vielen Dank und Grüsse aus Köln
May 3rd, 2013 - 15:00
Great piece of code. Thanks!