Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Yii unique validation on two columns of different tables ie. composite unique validation

I have two tables table1 and table2 each having a column named email along with different other columns. What I want is a validator which looks for uniqueness in email field of both the columns. I found an extension which checks multiple columns of SAME table. How can I extend it so that it works for multiple columns?

like image 695
dInGd0nG Avatar asked Jun 18 '12 17:06

dInGd0nG


2 Answers

You can use className property to specify for other classes..

Documentation: the ActiveRecord class name that should be used to look for the attribute value being validated. Defaults to null, meaning using the class of the object currently being validated. You may use path alias to reference a class name here.

Lets have an attribute called common_attr in two models:

class Model1 extends CActiveRecord{
    public function rules(){
        array('common_attr', 'unique', 'className'=> 'Model1'),
        array('common_attr', 'unique', 'className'=> 'Model2'),
    }
}

class Model2 extends CActiveRecord{
    public function rules(){
        array('common_attr', 'unique', 'className'=> 'Model1'),
        array('common_attr', 'unique', 'className'=> 'Model2'),
    }
}

And to check combined key validation from multiple tables you can use criteria property of CUniqueValidator.. No need for any extension

Documentation:criteria property public array $criteria; additional query criteria. This will be combined with the condition that checks if the attribute value exists in the corresponding table column. This array will be used to instantiate a CDbCriteria object.

class Model1 extends CActiveRecord{

    public function rules(){
        array('common_attr', 'unique', 'caseSensitive'=>false,
                   'criteria'=>array(
            'join'=>'LEFT JOIN model2 ON model2.common_attr=model1.common_attr',
                            'condition'=>'model2.common_attr=model1.common_attr',
        )),
    }
}
like image 97
Rajat Singhal Avatar answered Oct 22 '22 13:10

Rajat Singhal


In Yii2

Short:

['common_attr', 'unique'],
['common_attr', 'unique', 'targetClass' => AnotherClass::class],

Verbose:

class One extends \yii\db\ActiveRecord
{
    public function rules()
    {
        return [
            ['common_attr', 'unique'],
            ['common_attr', 'unique', 'targetClass' => Two::class],
        ];
    }
}

class Two extends \yii\db\ActiveRecord
{
    public function rules()
    {
        return [
            ['common_attr', 'unique'],
            ['common_attr', 'unique', 'targetClass' => One::class],
        ];
    }
}

Also, you can use a multiple unique key with targetAttribute:

[
    'common_attr', 
    'unique', 
    'targetClass' => One::class, 
    'targetAttribute' => ['common_attr', 'one_more_attr']
]
like image 26
German Khokhlov Avatar answered Oct 22 '22 12:10

German Khokhlov