Skip to content

Commit

Permalink
make UniqueValidator compatible with ActiveRecordInterface again
Browse files Browse the repository at this point in the history
  • Loading branch information
cebe committed Feb 1, 2017
1 parent 0df8020 commit 1eec5c1
Showing 1 changed file with 12 additions and 14 deletions.
26 changes: 12 additions & 14 deletions framework/validators/UniqueValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public function validateAttribute($model, $attribute)
$targetClass = $this->targetClass === null ? get_class($model) : $this->targetClass;
$targetAttribute = $this->targetAttribute === null ? $attribute : $this->targetAttribute;
$rawConditions = $this->prepareConditions($targetAttribute, $model, $attribute);
$conditions[] = $this->targetAttributeJunction == 'or' ? 'or' : 'and';
$conditions[] = $this->targetAttributeJunction === 'or' ? 'or' : 'and';

foreach ($rawConditions as $key => $value) {
if (is_array($value)) {
Expand Down Expand Up @@ -159,26 +159,24 @@ private function modelExists($targetClass, $conditions, $model)
// also there's no need to run check based on primary keys, when $targetClass is not the same as $model's class
$exists = $query->exists();
} else {
// if current $model is in the dat1abase already we can't use exists()
// if current $model is in the database already we can't use exists()
if ($query instanceof \yii\db\ActiveQuery) {
$models = $query->select($targetClass::primaryKey())->limit(2)->asArray()->all();
} else {
$models = $query->limit(2)->asArray()->all();
// only select primary key to optimize query
$query->select($targetClass::primaryKey());
}
$models = $query->limit(2)->asArray()->all();
$n = count($models);
if ($n === 1) {
$keys = array_keys($conditions);
// if there is one record, check if it is the currently validated model
$dbModel = reset($models);
$pks = $targetClass::primaryKey();
sort($keys);
sort($pks);
if ($keys === $pks) {
// primary key is modified and not unique
$exists = $model->getOldPrimaryKey() != $model->getPrimaryKey();
} else {
// non-primary key, need to exclude the current record based on PK
$exists = $models[0] != $model->getOldPrimaryKey(true);
$pk = [];
foreach($pks as $pkAttribute) {
$pk[$pkAttribute] = $dbModel[$pkAttribute];
}
$exists = ($pk != $model->getOldPrimaryKey(true));
} else {
// if there is more than one record, the value is not unique
$exists = $n > 1;
}
}
Expand Down

0 comments on commit 1eec5c1

Please sign in to comment.