Open
Description
The unlink() method bypasses the event triggering mechanism when the via is not null. It is not explained in the document, and I think this is not in line with my expectations. After all, it is not the unlinkAll() solution implemented.
version:2.0.49.3
public function unlink($name, $model, $delete = false)
{
/* @var $relation ActiveQueryInterface|ActiveQuery */
$relation = $this->getRelation($name);
if ($relation->via !== null) {
if (is_array($relation->via)) {
/* @var $viaRelation ActiveQuery */
list($viaName, $viaRelation) = $relation->via;
$viaClass = $viaRelation->modelClass;
unset($this->_related[$viaName]);
} else {
$viaRelation = $relation->via;
$viaTable = reset($relation->via->from);
}
$columns = [];
foreach ($viaRelation->link as $a => $b) {
$columns[$a] = $this->$b;
}
foreach ($relation->link as $a => $b) {
$columns[$b] = $model->$a;
}
$nulls = [];
foreach (array_keys($columns) as $a) {
$nulls[$a] = null;
}
if (property_exists($viaRelation, 'on') && $viaRelation->on !== null) {
$columns = ['and', $columns, $viaRelation->on];
}
if (is_array($relation->via)) {
/* @var $viaClass ActiveRecordInterface */
if ($delete) {
$viaClass::deleteAll($columns);
} else {
$viaClass::updateAll($nulls, $columns);
}
} else {
/* @var $viaTable string */
/* @var $command Command */
$command = static::getDb()->createCommand();
if ($delete) {
$command->delete($viaTable, $columns)->execute();
} else {
$command->update($viaTable, $nulls, $columns)->execute();
}
}
} else {
$p1 = $model->isPrimaryKey(array_keys($relation->link));
$p2 = static::isPrimaryKey(array_values($relation->link));
if ($p2) {
if ($delete) {
$model->delete();
} else {
foreach ($relation->link as $a => $b) {
$model->$a = null;
}
$model->save(false);
}
} elseif ($p1) {
foreach ($relation->link as $a => $b) {
if (is_array($this->$b)) { // relation via array valued attribute
if (($key = array_search($model->$a, $this->$b, false)) !== false) {
$values = $this->$b;
unset($values[$key]);
$this->$b = array_values($values);
}
} else {
$this->$b = null;
}
}
$delete ? $this->delete() : $this->save(false);
} else {
throw new InvalidCallException('Unable to unlink models: the link does not involve any primary key.');
}
}
if (!$relation->multiple) {
unset($this->_related[$name]);
} elseif (isset($this->_related[$name])) {
/* @var $b ActiveRecordInterface */
foreach ($this->_related[$name] as $a => $b) {
if ($model->getPrimaryKey() === $b->getPrimaryKey()) {
unset($this->_related[$name][$a]);
}
}
}
}
Metadata
Metadata
Assignees
Labels
No labels