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,...'), ); }
Yii 1.0 or above
public function rules() { return array( array('firstKey', 'UniqueAttributesValidator', 'with'=>'secondKey,thirdKey,...'), ); }
Total 8 comments
Thanks for this great extension, which works like a charm. But I noticed it's not working if one attribute is NULL. This is because in MySQL a comparison to NULL always returns false. e.g.
will give 0 Rows even if there are rows col = NULL
So you have to compare using IS NULL in MySQL e.g.
To solve this, I slightly modified your extension:
The interesting Part is form line 13 to 15, which checks the value for NULL and modifies the query.
abhishek2890
I downloaded to /protected/extensions/
and I add this rule: array('nro_documento', 'ext.UniqueAttributesValidator', 'with'=>'fk_tipodocumento_id'),
Be aware of "ext" prefix ! Work like a charm.
Regards
I am not understanding that,where to put file UniqueAttributesValidator.php
I agreee, this extensions should be integrated with yii core! :)
Ah indeed, a bug in the documentation! It should be array('firstKey', 'UniqueAttributesValidator', 'with'=>'secondKey'), And for more attributes you can comma-seperate them: array('firstKey', 'UniqueAttributesValidator', 'with'=>'secondKey,thridKey,...'), I will update the documentation.
To override the default error message you can set the 'message' property, the extension will pass that to the CUniqueValidator
wonderful,
i have been waiting this extension.. but seem not work when I use:
array('firstKey', 'UniqueAttributesValidator', 'with'=>array('secondKey')),
the error said like this
explode() expects parameter 2 to be string, array given ..
error on line 17: $with = explode(",", $this->with);
but it work when I use this
array('firstKey', 'UniqueAttributesValidator', 'with'=>'secondKey'),
:-D ...
Probably, you may add ErrorMessage on this extension, so it will override the default error message that come only for firstKey..
But overall, this is a good extension.. Thank you..
Thank you for the appreciation.
Good point intergrate this into CUniqueValidator. In that case the mapping of 'unique'=>'CUniqueValidator' should be 'unique'=>'UniqueValidator'. Do you have a suggestion how to achieve this in the configuration file?
A solution would be to put CUniqueValidator::$builtInValidators['unique']='UniqueValidator'; somewhere in the beginning of the request, but in that case CValidator will be loaded every request instead of lazy-loaded.
thanks for sharing !actually i seldom met the composite unique constraint . but your work is helpful and give a good example for using 'unique' validator of yiis on this situation . and your extension is also save us a lot of time .
by the way , it seems better to integrate this functionality to the core CUniqueValidator , just add another attribute : 'with' .
Leave a comment
Please login to leave your comment.