BelongsToMany relation updateOrCreate logic.

@param array    $fillable The relation fillable.
@param Model    $model    The eloquent model.
@param Relation $relation The eloquent relation.

@return array
971323
protected function updateOrCreateBelongsToMany(array $fillable, Model $model, Relation $relation)
    {
        $keys = [];
        $records = [];

        $related = $relation->getRelated();

        foreach ($fillable as $fields) {
            if (array_key_exists('id', $fields)) {
                $id = $fields['id'];
                array_push($keys, $id);
            } else {
                $id = '';
            }

            if (array_except($fields, ['id'])) {
                $record = $related->updateOrCreate(['id' => $id], $fields);
                array_push($keys, $record->id);
                array_push($records, $record);
            }
        }

        $relation->sync($keys);

        return $records;
    }
106541
private function sortInputAndApply(Model &$model, $update = false)
    {
        // Loop through all input
        if ($update) {
            foreach (Input::all() as $key => $value) {
                // Check to see if there is any available value for the desired model.
                if (!empty($model->$key)) {
                    // If the value is not equal to the desired value
                    if ($model->$key !== $value) {
                        // Remove any extra spaces
                        $model->$key = $this->manageInput($key, $value);
                    }
                } elseif (Input::has('_relations')) {
                    // Explode any potential relations.
                    $relations = explode(',', Input::get('_relations'));
                    foreach ($relations as $relation) {
                        // If the relation has the key, update the value.
                        if (!empty($model->$relation->$key)) {
                            if ($model->$relations->$key !== $value) {
                                $model->$relations->$key = $this->manageInput($key, $value);
                            }
                        }
                    }
                }
            }
        } else {
            foreach ($model->getFillable() as $key) {
                foreach (Input::all() as $field => $value) {
                    // If the fillable key doesn't match the input
                    // field keep going,Otherwise, set the values.
                    if ($key === $field) {
                        $model->$key = $this->manageInput($key, $value);
                    }
                }
            }
        }
        // Unconventional return?
        return $model;
    }
417102
protected function updateOrCreateBelongsToOne(array $fillable, Model $model, Relation $relation)
    {
        $related = $relation->getRelated();

        if (array_except($fillable, ['id'])) {
            if (!$relation->first()) {
                $record = $relation->associate($related->create($fillable));
                $model->save();
            } else {
                $record = $relation->update($fillable);
            }

            return $record;
        }

        return null;
    }
332056
protected function fill(Model $instance): bool
	{
		$input = $this->getInput();
		$model_fields = $this->getFields($instance);
		$before_relations = [];
		$after_relations = [];
		$instance_model = get_class($instance);
		$safe_instance = new $instance_model;

		$input = ($safe_instance->getIncrementing()) ? array_except($input, [$instance->getKeyName()]) : $input;

		foreach ($input as $key => $value) {
			if (($relation = $this->isRelation($instance, $key, $instance_model)) && $this->isFillable($key)) {
				$relation_type = get_class($relation);

				switch ($relation_type) {
					case BelongsTo::class:
						$before_relations[] = [
							'relation' => $relation,
							'value' => $value,
						];
						break;
					case HasOne::class:
					case HasMany::class:
					case BelongsToMany::class:
						$after_relations[] = [
							'relation' => $relation,
							'value' => $value,
						];
						break;
				}
			} elseif ((in_array($key, $model_fields) || $instance->hasSetMutator($key)) && $this->isFillable($key)) {
				$instance->{$key} = $value;
			}
		}

		unset($safe_instance);

		$this->applyRelations($before_relations, $instance);
		$instance->save();
		$this->applyRelations($after_relations, $instance);

		return true;
	}
398280
protected function syncBelongsToManyRelation(
        \Illuminate\Database\Eloquent\Relations\BelongsToMany $relation,
        array $values
    ) {
        foreach ($values as $i => $value) {
            if (! array_key_exists($value, $this->getOptions()) && $this->isTaggable()) {
                $model = clone $this->getModelForOptions();
                $model->{$this->getDisplay()} = $value;
                $model->save();

                $values[$i] = $model->getKey();
            }
        }

        if (is_callable($callback = $this->getSyncCallback())) {
            $callbackModel = $this->getModel();
            $callback($values, $callbackModel);

            return;
        }

        $relation->sync($values);
    }
1126517
public function populateJoinedRelations($model, array $row)
    {
        foreach ($row as $key => $value) {
            if (empty($this->join) || !is_array($value) || $model->hasAttribute($key)) {
                continue;
            }
            foreach ($this->join as $join) {
                $keys = array_keys($join);
                $name = array_shift($keys);
                $closure = array_shift($join);

                if (is_int($name)) {
                    $name = $closure;
                    $closure = null;
                }
                if ($name !== $key) {
                    continue;
                }
                if ($model->isRelationPopulated($name)) {
                    continue 2;
                }
                $records = [];
                $relation = $model->getRelation($name);
                $relationClass = $relation->modelClass;
                if ($closure !== null) {
                    call_user_func($closure, $relation);
                }
                $relation->prepare();

                if ($relation->multiple) {
                    foreach ($value as $item) {
                        $relatedModel = $relationClass::instantiate($item);
                        $relatedModelClass = get_class($relatedModel);
                        $relatedModelClass::populateRecord($relatedModel, $item);
                        $relation->populateJoinedRelations($relatedModel, $item);
                        $relation->addInverseRelation($relatedModel, $model);
                        $relatedModel->trigger(BaseActiveRecord::EVENT_AFTER_FIND);
                        if ($relation->indexBy !== null) {
                            $index = is_string($relation->indexBy)
                                ? $relatedModel[$relation->indexBy]
                                : call_user_func($relation->indexBy, $relatedModel);
                            $records[$index] = $relatedModel;
                        } else {
                            $records[] = $relatedModel;
                        }
                    }
                } else {
                    $relatedModel = $relationClass::instantiate($value);
                    $relatedModelClass = get_class($relatedModel);
                    $relatedModelClass::populateRecord($relatedModel, $value);
                    $relation->populateJoinedRelations($relatedModel, $value);
                    $relation->addInverseRelation($relatedModel, $model);
                    $relatedModel->trigger(BaseActiveRecord::EVENT_AFTER_FIND);
                    $records = $relatedModel;
                }

                $model->populateRelation($name, $records);
            }
        }
    }
1109624
private function fillRelationshipAsCollection($data, $relationship, $key)
    {
        foreach ($relationship as $index => $relationshipData) {
            $data['data'][$index]['relationships'][$key] = $relationshipData;

            if ($this->shouldIncludeLinks()) {
                $data['data'][$index]['relationships'][$key] = array_merge([
                    'links' => [
                        'self' => "{$this->baseUrl}/{$data['data'][$index]['type']}/{$data['data'][$index]['id']}/relationships/$key",
                        'related' => "{$this->baseUrl}/{$data['data'][$index]['type']}/{$data['data'][$index]['id']}/$key",
                    ],
                ], $data['data'][$index]['relationships'][$key]);
            }
        }

        return $data;
    }
469232
protected function makeModelFormFieldDataForRelationData(ModelRelationData $relation, $key = null)
    {
        $required = (   in_array($relation->type, [
                            RelationType::BELONGS_TO,
                            RelationType::BELONGS_TO_THROUGH,
                            RelationType::MORPH_TO,
                        ])
                    &&  ! $relation->nullable_key);

        // Shows any relation, regardless of type. Note that this is not optimal for
        // records with a large number of to-many related items, for instance.

        return new ModelFormFieldData([
            'key'              => $key ?: $relation->name,
            'source'           => $relation->method,
            'required'         => $required,
            'translated'       => $relation->translated,
            'display_strategy' => $this->determineFormDisplayStrategyForRelation($relation),
            'store_strategy'   => $this->determineFormStoreStrategyForRelation($relation),
            'options'          => $this->determineFormStoreOptionsForRelation($relation),
        ]);
    }
173144
private static function relations()
    {
        $files = ['OneToOne', 'OneToMany', 'ManyToMany', 'BelongsTo'];
        $folder = static::$root.'MVC/Relations'.'/';

        self::call($files, $folder);

        $files = ['ManyRelationException', 'ModelNotFindedException'];
        $folder = static::$root.'MVC/Relations/Exceptions'.'/';

        self::call($files, $folder);
    }
924080
private function _checkRelationExists(Model $model, string $relationName)
    {
        if (!method_exists($model, $relationName) || !$model->{$relationName}() instanceof Relation) {
            if (Lang::has('resource-controller.data2relationinexistent')) {
                $message = trans('resource-controller.data2relationinexistent', ['relationName' => $relationName]);
            } else {
                $message = "Array type request data '{$relationName}' must be named after an existent relation.";
            }

            throw new MassAssignmentException($message);
        }
    }
929083
private function joinWithRelations($model, $with, $joinType)
    {
        $relations = [];

        foreach ($with as $name => $callback) {
            if (is_int($name)) {
                $name = $callback;
                $callback = null;
            }

            $primaryModel = $model;
            $parent = $this;
            $prefix = '';
            while (($pos = strpos($name, '.')) !== false) {
                $childName = substr($name, $pos + 1);
                $name = substr($name, 0, $pos);
                $fullName = $prefix === '' ? $name : "$prefix.$name";
                if (!isset($relations[$fullName])) {
                    $relations[$fullName] = $relation = $primaryModel->getRelation($name);
                    $this->joinWithRelation($parent, $relation, $this->getJoinType($joinType, $fullName));
                } else {
                    $relation = $relations[$fullName];
                }
                $primaryModel = new $relation->modelClass;
                $parent = $relation;
                $prefix = $fullName;
                $name = $childName;
            }

            $fullName = $prefix === '' ? $name : "$prefix.$name";
            if (!isset($relations[$fullName])) {
                $relations[$fullName] = $relation = $primaryModel->getRelation($name);
                if ($callback !== null) {
                    call_user_func($callback, $relation);
                }
                if (!empty($relation->joinWith)) {
                    $relation->buildJoinWith();
                }
                $this->joinWithRelation($parent, $relation, $this->getJoinType($joinType, $fullName));
            }
        }
    }
160794
public function initRelation(array $models, $relation)
    {
        foreach ($models as $model) {
            $model->setRelation($relation, $this->getDefaultFor($model));
        }

        return $models;
    }
592795
public static function normalizeToManyRelation($relation, $relationship)
    {
        if (is_array($relation)) {
            $relation = new ArrayCollection($relation);
        } elseif (is_null($relation)) {
            throw new \Exception(sprintf(
                self::ERROR_TO_MANY_RELATION_NULL, $relationship
            ));
        } elseif (!$relation instanceof CollectionInterface) {
            $type = is_object($relation)
                ? get_class($relation)
                : gettype($relation);

            throw new \Exception(sprintf(
                self::ERROR_NOT_ENTITY_COLLECTION, $relationship, $type
            ));
        }

        return $relation;
    }
157840
public static function make($model, $relation)
    {
        $class = get_class($model);

        $instance = new static("Call to undefined relationship [{$relation}] on model [{$class}].");

        $instance->model = $model;
        $instance->relation = $relation;

        return $instance;
    }
421952
public function addRelation(Relation $relation) {
        $relation->setPrimaryModel($this);

        $this->_relations[$relation->getAlias()] = $relation;
        $this->_aliases[$relation->getRelatedClass()] = $relation->getAlias();
        $this->reserved[] = $relation->getAlias();

        $this->on('relation', $relation);

        return $this;
    }
305759
protected function newPivotQuery(BelongsToMany $relation)
    {
        $query = $relation->newPivotStatement()->where(
            $this->getForeignPivotKeyName($relation),
            $relation->getParent()->getKey()
        );

        return Models::scope()->applyToRelationQuery(
            $query, $relation->getTable()
        );
    }
964095
public function addRelation(Relation $relation)
    {
        switch (get_class($relation)) {
            case BelongsTo::class:
                $this->relations['belongsTo'][] = $relation;
                break;

            case BelongsToMany::class:
                $this->relations['belongsToMany'][] = $relation;
                break;

            case HasOne::class:
                $this->relations['hasOne'][] = $relation;
                break;

            case HasMany::class:
                $this->relations['hasMany'][] = $relation;
                break;

            case HasManyThrough::class:
                $this->relations['hasManyThrough'][] = $relation;
                break;

            default:
                throw new \Exception("Unknown relation type " . get_class($relation));
        }
    }