Browse Source

Merge pull request #13487 from yiisoft/unique-validator

Unique validator
tags/2.0.11
Carsten Brandt 8 years ago committed by GitHub
parent
commit
72cd849f5f
  1. 24
      framework/validators/UniqueValidator.php

24
framework/validators/UniqueValidator.php

@ -120,7 +120,7 @@ class UniqueValidator extends Validator
$targetClass = $this->targetClass === null ? get_class($model) : $this->targetClass; $targetClass = $this->targetClass === null ? get_class($model) : $this->targetClass;
$targetAttribute = $this->targetAttribute === null ? $attribute : $this->targetAttribute; $targetAttribute = $this->targetAttribute === null ? $attribute : $this->targetAttribute;
$rawConditions = $this->prepareConditions($targetAttribute, $model, $attribute); $rawConditions = $this->prepareConditions($targetAttribute, $model, $attribute);
$conditions[] = $this->targetAttributeJunction == 'or' ? 'or' : 'and'; $conditions[] = $this->targetAttributeJunction === 'or' ? 'or' : 'and';
foreach ($rawConditions as $key => $value) { foreach ($rawConditions as $key => $value) {
if (is_array($value)) { if (is_array($value)) {
@ -160,21 +160,23 @@ class UniqueValidator extends Validator
$exists = $query->exists(); $exists = $query->exists();
} else { } else {
// if current $model is in the database already we can't use exists() // if current $model is in the database already we can't use exists()
$models = $query->select($targetClass::primaryKey())->limit(2)->createCommand()->queryAll(); if ($query instanceof \yii\db\ActiveQuery) {
// only select primary key to optimize query
$query->select($targetClass::primaryKey());
}
$models = $query->limit(2)->asArray()->all();
$n = count($models); $n = count($models);
if ($n === 1) { 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(); $pks = $targetClass::primaryKey();
sort($keys); $pk = [];
sort($pks); foreach($pks as $pkAttribute) {
if ($keys === $pks) { $pk[$pkAttribute] = $dbModel[$pkAttribute];
// 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);
} }
$exists = ($pk != $model->getOldPrimaryKey(true));
} else { } else {
// if there is more than one record, the value is not unique
$exists = $n > 1; $exists = $n > 1;
} }
} }

Loading…
Cancel
Save