Delete all old models for attribute if it needed

@param $attribute
@throws RelationException
355714
protected function deleteModels($attribute)
    {
        $data = $this->relationalData[$attribute];

        /** @var ActiveRecord $model */
        foreach ($data['oldModels'] as $model) {
            if ($this->isDeletedModel($model, $attribute)) {
                if (!$model->delete()) {
                    Yii::$app->getDb()->getTransaction()->rollBack();
                    throw new RelationException('Model ' . $model::className() . ' not deleted due to unknown error');
                }
            }
        }

        $this->relationsMap($data['oldRows'], function($row) use ($attribute, $data) {
            if ($this->isDeletedRow($row, $attribute)) {
                Yii::$app->db->createCommand()
                    ->delete($data['junctionTable'], $row)
                    ->execute();
            }
        });
    }
642960
protected function loadModelsOneToMany($attribute)
    {
        $data = $this->relationalData[$attribute];
        
        $activeQuery = $data['activeQuery'];
        $class = $activeQuery->modelClass;

        // default query conditions
        $params = !ArrayHelper::isAssociative($activeQuery->on) ? [] : $activeQuery->on;
        // one-to-many
        foreach ($activeQuery->link as $childAttribute => $parentAttribute) {
            $params[$childAttribute] = $this->owner->$parentAttribute;
        }

        if (!empty($data['data'])) {
            foreach ($data['data'] as $attributes) {
                $model = new $class(
                    array_merge(
                        $params,
                        ArrayHelper::isAssociative($attributes) ? $attributes : []
                    )
                );
                if (isset($this->relations[$attribute]) && is_callable($this->relations[$attribute])) {
                    $model = call_user_func($this->relations[$attribute], $model, $attributes);
                }
                $data['newModels'][] = $model;
            }
        }

        $this->relationalData[$attribute] = $data;
    }
322662
public function removeAttribute(string $attribute): self
    {
        // Determine if the attribute is present, unset if present
        if (array_key_exists($attribute, $this->attributes)) {
            unset($this->attributes[$attribute]);
        }

        return $this;
    }
326138
protected function loadModelsManyToManyViaTable($attribute)
    {
        $data = $this->relationalData[$attribute];

        $activeQuery = $data['activeQuery'];
        /** @var ActiveRecord $class */
        $class = $activeQuery->modelClass;

        $via = $activeQuery->via;
        $data['junctionTable'] = $via->from[0];

        list($data['junctionColumn']) = array_keys($via->link);
        list($data['relatedColumn']) = array_values($activeQuery->link);
        $junctionColumn = $data['junctionColumn'];
        $relatedColumn = $data['relatedColumn'];

        if (!empty($data['data'])) {
            // make sure what all row's ids from POST exists in database
            $countManyToManyModels = $class::find()->where([$class::primaryKey()[0] => $data['data']])->count();
            if ($countManyToManyModels != count($data['data'])) {
                throw new RelationException('Related records for attribute ' . $attribute . ' not found');
            }
            // create new junction rows
            foreach ($data['data'] as $relatedModelId) {
                $junctionModel = array_merge(
                    !ArrayHelper::isAssociative($via->on) ? [] : $via->on,
                    [$junctionColumn => $this->owner->getPrimaryKey()]
                );
                $junctionModel[$relatedColumn] = $relatedModelId;
                if (isset($this->relations[$attribute]) && is_callable($this->relations[$attribute])) {
                    $junctionModel = call_user_func($this->relations[$attribute], $junctionModel, $relatedModelId);
                }
                $data['newRows'][] = $junctionModel;
            }
        }

        if (!empty($this->owner->getPrimaryKey())) {
            $data['oldRows'] = (new Query())
                ->from($data['junctionTable'])
                ->select(array_merge(
                        [$junctionColumn, $relatedColumn],
                        !ArrayHelper::isAssociative($via->on) ? [] : array_keys($via->on))
                )->where(array_merge(
                    !ArrayHelper::isAssociative($via->on) ? [] : $via->on,
                    [$junctionColumn => $this->owner->getPrimaryKey()]
                ))->all();
        }

        $this->relationalData[$attribute] = $data;
    }
1325635
public function remove($attributes)
    {
        foreach ((array) $attributes as $attribute) {
            unset($this->defaults[$attribute],
                $this->types[$attribute],
                $this->requires[$attribute],
                $this->notNullables[$attribute]);
        }

        return $this;
    }
659855
public function delete($entity)
    {
        $eloquentModel = $this->getEloquentModel($entity, true);

        $this->updateRelations($eloquentModel, 'delete');

        $eloquentModel->delete();
    }
1001877
public function _update_original_relations($relations = null)
	{
		if (is_null($relations))
		{
			$this->_original_relations = array();
			$relations = $this->_data_relations;
		}
		else
		{
			foreach ($relations as $key => $rel)
			{
				// Unload the just fetched relation from the originals
				unset($this->_original_relations[$rel]);

				// Unset the numeric key and set the data to update by the relation name
				unset($relations[$key]);
				$relations[$rel] = $this->_data_relations[$rel];
			}
		}

		foreach ($relations as $rel => $data)
		{
			if (is_array($data))
			{
				$this->_original_relations[$rel] = array();
				foreach ($data as $obj)
				{
					if ($obj and ! $obj->is_new())
					{
						$this->_original_relations[$rel][] = $obj->implode_pk($obj);
					}
				}
			}
			else
			{
				$this->_original_relations[$rel] = null;
				if ($data and ! $data->is_new())
				{
					$this->_original_relations[$rel] = $data->implode_pk($data);
				}
			}
		}
	}
1131973
public function delete()
    {
        /**
         * Check for many2many attributes and make sure related Entity has a corresponding many2many attribute defined.
         * If not - deleting is not allowed.
         */

        /* @var $attr Many2ManyAttribute */
        $thisClass = get_class($this);
        foreach ($this->getAttributes() as $attrName => $attr) {
            if ($this->isInstanceOf($attr, AttributeType::MANY2MANY)) {
                $foundMatch = false;
                $relatedClass = $attr->getEntity();
                $relatedEntity = new $relatedClass;
                /* @var $relAttr Many2ManyAttribute */
                foreach ($relatedEntity->getAttributes() as $relAttr) {
                    if ($this->isInstanceOf($relAttr, AttributeType::MANY2MANY) && $this->isInstanceOf($this, $relAttr->getEntity())) {
                        $foundMatch = true;
                    }
                }

                if (!$foundMatch) {
                    throw new EntityException(EntityException::NO_MATCHING_MANY2MANY_ATTRIBUTE_FOUND, [
                        $thisClass,
                        $relatedClass,
                        $attrName
                    ]);
                }
            }
        }

        /**
         * First check all one2many records to see if deletion is restricted
         */
        $one2manyDelete = [];
        $many2oneDelete = [];
        $many2manyDelete = [];
        foreach ($this->getAttributes() as $key => $attr) {
            if ($this->isInstanceOf($attr, AttributeType::ONE2MANY)) {
                if ($attr->getOnDelete() == 'ignore') {
                    continue;
                }

                /* @var $attr One2ManyAttribute */
                if ($attr->getOnDelete() == 'restrict' && $this->getAttribute($key)->getValue()->count() > 0) {
                    throw new EntityException(EntityException::ENTITY_DELETION_RESTRICTED, [$key]);
                }
                $one2manyDelete[] = $attr;
            }

            if ($this->isInstanceOf($attr, AttributeType::MANY2ONE)) {
                /* @var $attr Many2OneAttribute */
                if ($attr->getOnDelete() === 'cascade') {
                    $many2oneDelete[] = $attr;
                }
                continue;
            }

            if ($this->isInstanceOf($attr, AttributeType::MANY2MANY)) {
                $many2manyDelete[] = $attr;
            }
        }

        /**
         * Delete one2many records
         */
        foreach ($one2manyDelete as $attr) {
            foreach ($attr->getValue() as $item) {
                $item->delete();
            }
        }

        /**
         * Delete many2many records
         */
        foreach ($many2manyDelete as $attr) {
            $attr->unlinkAll();
        }

        /**
         * Delete many2one records that are set to 'cascade'
         */
        foreach ($many2oneDelete as $attr) {
            $value = $attr->getValue();
            if ($value && $value instanceof AbstractEntity) {
                $value->delete();
            }
        }

        /**
         * Delete $this
         */
        $this->entity()->getDatabase()->delete(static::$collection, ['_id' => $this->entity()->getDatabase()->id($this->id)]);

        static::entity()->remove($this);

        return true;
    }
1355918
public function removeAttribute($attributes)
    {
        if (is_string($attributes)) {
            $attributes = explode(',', $attributes);
        }

        $attributes = array_map('trim', $attributes);
        $attributes = array_filter($attributes);

        foreach ($attributes as $attribute) {
            if (array_key_exists($attribute, $this->storage)) {
                unset($this->storage[ $attribute ]);
            } elseif (strpos($attribute, '*') !== false) {
                $attribute = str_replace('*', '', $attribute);
                foreach ($this->storage as $key => $value) {
                    if (preg_match("/\b$attribute\b/i", $key)) {
                        unset($this->storage[ $key ]);
                    }
                }
            }
        }
    }
45013
protected function takeAttributeFromDOM($attribute)
    {
        switch ($attribute->localName) {
            case 'name':
                $name = explode(':', $attribute->nodeValue);
                $this->_name = end($name);
                break;
            case 'value':
                $this->_value = $attribute->nodeValue;
                break;
            default:
                parent::takeAttributeFromDOM($attribute);
        }
    }
396816
public function delete($table, $attribute)
    {
        $this->tableName = $table;

        if (is_array($attribute)) {
            return $this->trash($attribute, true);
        } elseif (is_string($attribute) || is_int($attribute)) {
            return $this->trash($attribute);
        }
    }
783599
public function isAutomaticallyUpdatedDate($attribute)
    {
        // soft deletes
        if (in_array('Illuminate\Database\Eloquent\SoftDeletes', class_uses(static::class)) && $attribute == $this->getDeletedAtColumn()) {
            return true;
        }

        // timestamps
        if ($this->timestamps && ($attribute == $this->getCreatedAtColumn() || $attribute == $this->getUpdatedAtColumn())) {
            return true;
        }
        
        return false;
    }
942930
public function setRelated($value)
    {
        $this->loadData(true);

        if (is_null($value)) {
            $value = [];
        }

        if (!is_array($value)) {
            throw new RelationException("HasMany relation can only be set with array of entities");
        }

        //Do not add items twice
        $matched = [];
        foreach ($value as $index => $item) {
            if (is_null($item)) {
                unset($value[$index]);
                continue;
            }

            $this->assertValid($item);
            if (!empty($instance = $this->matchOne($item))) {
                $matched[] = $instance;
                unset($value[$index]);
            }
        }

        $this->deleteInstances = array_diff($this->instances, $matched);
        $this->instances = $matched + $value;
    }
28501
public function setRelated($value)
    {
        $this->loadData(true);

        if (is_null($value)) {
            $value = [];
        }

        if (!is_array($value)) {
            throw new RelationException("HasMany relation can only be set with array of entities");
        }

        //Do not add items twice
        $matched = [];
        foreach ($value as $index => $record) {
            if (is_null($record)) {
                unset($value[$index]);
                continue;
            }

            $this->assertValid($record);
            if (!empty($instance = $this->matchOne($record))) {
                $matched[] = $instance;
                unset($value[$index]);
            }
        }

        //Unlink records
        foreach (array_diff($this->instances, $matched) as $record) {
            $this->unlink($record);
        }

        //Add new record
        foreach ($value as $record) {
            $this->link($record);
        }
    }
799974
protected function auditDeletedAttributes(array &$old, array &$new)
    {
        foreach ($this->attributes as $attribute => $value) {
            if ($this->isAttributeAuditable($attribute)) {
                $old[$attribute] = $value;
            }
        }
    }
137581
public function unbind($name)
    {
        if (!isset($this->_relations[$name])) {
            return;
        }
        unset($this->_relations[$name]);
        unset($this->_relationships[$name]);
    }
1098990
private function checkAttrExists($attribute)
    {
        foreach ($this->attributes as $attr => $options) {
            $this->ensureAttributes($attr, $options);
            if ($attr == $attribute) {
                return;
            }
        }
        throw new InvalidParamException();
    }