mirror of
https://github.com/yiisoft/yii2.git
synced 2025-08-26 14:26:54 +08:00
make UniqueValidator compatible with ActiveRecordInterface again
fixes #13485
This commit is contained in:
@ -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)) {
|
||||||
@ -159,26 +159,24 @@ class UniqueValidator extends Validator
|
|||||||
// also there's no need to run check based on primary keys, when $targetClass is not the same as $model's class
|
// 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();
|
$exists = $query->exists();
|
||||||
} else {
|
} 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) {
|
if ($query instanceof \yii\db\ActiveQuery) {
|
||||||
$models = $query->select($targetClass::primaryKey())->limit(2)->asArray()->all();
|
// only select primary key to optimize query
|
||||||
} else {
|
$query->select($targetClass::primaryKey());
|
||||||
$models = $query->limit(2)->asArray()->all();
|
|
||||||
}
|
}
|
||||||
|
$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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user