Upserts one to many relationships

@param $attributes Model attributes
@return object Model instance
335307
private function updateHasMany($id, $attributes)
    {
        // Return if the ID is invalid, or attributes is not an array
        if (!isset($id) || !isset($attributes) || empty($attributes)) {
            return $this;
        }

        // Return if there are no relationships of that type
        if (!isset($this->relationships['hasMany']) || empty($this->relationships['hasMany'])) {
            return $this;
        }

        // Sync each relationship
        foreach ($this->relationships['hasMany'] as $join) {

            // The sync option has to be set, the related attribute an array
            if (isset($join['sync']) && is_array($join['sync']) && isset($attributes[$join['alias']]) && is_array($attributes[$join['alias']])) {

                // Get related elements
                $related = $attributes[$join['alias']];

                // Write trough the model
                if (isset($join['model'])) {

                    // Get or instance the related model
                    if (isset($this->models) && isset($this->models[$join['model']])) {
                        $instance = $this->models[$join['model']];
                    } else {
                        $instance = new $join['model'];
                    }

                    // Delete elements if the overwrite option was set
                    if (in_array('overwrite', $join['sync'])) {
                        $results = $instance->where($join['foreignKey'], $id, '=', $instance->getTable())->limit($join['limit'])->get();
                        if ($results) {
                            foreach ($results as $result) {
                                $instance->destroy($result[$instance->getPrimaryKey()]);
                            }
                        }
                    }

                    // Iterate related elements
                    foreach ($related as $value) {

                        // Add the foreign key
                        $value[$join['foreignKey']] = $id;

                        // Insert elements whitout ID
                        if (in_array('insert', $join['sync']) && !isset($value['id'])) {
                            $instance->create($value);
                        }

                        // Update elements width ID
                        if (in_array('update', $join['sync']) && isset($value['id'])) {

                            // Check if the existing element belongs to this record
                            $current = $instance->find($value['id']);
                            if ($current && isset($current[$join['foreignKey']]) && $current[$join['foreignKey']] == $id) {
                                $instance->update($value['id'], $value);
                            }
                        }
                    }
                }

                // Write trough database
                if (!isset($join['model'])) {

                    // Delete elements if the overwrite option was set
                    if (in_array('overwrite', $join['sync'])) {
                        $results = $this->db()->table($join['table'])->where($join['foreignKey'], $id)->limit(100)->get();
                        if ($results) {
                            $ids = array_diff(array_column($results, 'id'), array_column($related, 'id'));
                            $this->db()->table($join['table'])->whereIn('id', $ids)->delete();
                        }
                    }

                    // Iterate related elements
                    foreach ($related as $value) {

                        // Leave only writable fields
                        $fields = array_intersect_key($value, array_flip($join['columns']));

                        // Add the foreign key
                        $fields[$join['foreignKey']] = $id;

                        // Insert elements whitout ID
                        if (in_array('insert', $join['sync']) && !isset($value['id'])) {
                            $this->db()->table($join['table'])->insert($fields);
                        }

                        // Update elements width ID
                        if (in_array('update', $join['sync']) && isset($value['id'])) {

                            // Check if the existing element belongs to this record
                            $current = $this->db()->table($join['table'])->where('id', $value['id'])->limit(1)->getOne();
                            if ($current && isset($current[$join['foreignKey']]) && $current[$join['foreignKey']] == $id) {
                                $this->db()->table($join['table'])->where('id', $value['id'])->update($fields);
                            }
                        }
                    }
                }
            }
        }

        // Return model instance
        return $this;
    }
824666
public function fill(array $attributes = [])
    {
        $this->raw = $attributes;

        $excludes = config("api.excludes");

        foreach ($attributes as $key => $attribute) {
            // Guarded attributes should be removed
            if (in_array($key, $excludes)) {
                unset($attributes[$key]);
            }
            else if (method_exists($this, $key) && ((is_array($attribute) || is_null($attribute)))) {
                // Its a relation
                $this->relationAttributes[$key] = $attribute;

                // For belongs to relation, while filling, we need to set relation key.
                $relation = call_user_func([$this, $key]);

                if ($relation instanceof BelongsTo) {
                    $primaryKey = $relation->getRelated()->getKeyName();

                    if ($attribute !== null) {
                        // If key value is not set in request, we create new object
                        if (!isset($attribute[$primaryKey])) {
                            throw new RelatedResourceNotFoundException('Resource for relation "' . $key . '" not found');
                        }
                        else {
                            $model = $relation->getRelated()->find($attribute[$primaryKey]);

                            if (!$model) {
                                // Resource not found
                                throw new ResourceNotFoundException();
                            }
                        }
                    }

                    $relationKey = $relation->getForeignKey();

                    $this->setAttribute($relationKey, ($attribute === null) ? null : $model->getKey());
                }

                unset($attributes[$key]);
            }
        }

        return parent::fill($attributes);
    }
351630
public function create(array $attributes = null)
    {
        $this->doQuery($this->createQuery($attributes));
        $this->{static::$PKFieldName[0]} = static::db()->lastInsertId();
        if ($attributes) {
            $this->fillProperties($attributes);
        }

        return $this;
    }
993361
public function create(array $attributes = [])
    {
        return tap($this->related->newInstance($attributes), function ($instance) {
            $foreignKey = $this->getForeignKeyName();
            $parentKeyValue = $this->getParentKey();

            if (is_array($foreignKey)) { //Check for multi-columns relationship
                foreach ($foreignKey as $index => $key) {
                    $instance->setAttribute($key, $parentKeyValue[$index]);
                }
            } else {
                $instance->setAttribute($foreignKey, $parentKeyValue);
            }

            $instance->save();
        });
    }
1148503
public function mergeAttributes($attributes)
    {
        $attributes = self::prepareAttributes($attributes);
        foreach ($this->watchedAttributes as $watchedKey) {
            if (isset($attributes[$watchedKey])) {
                $this->onAttributeChange($watchedKey, $attributes[$watchedKey]);
                unset($attributes[$watchedKey]);
            }
        }
        $this->attributes = array_merge($this->attributes, $attributes);
        return $this;
    }
779555
public function setAttributes(array $attributes = null)
    {
        ValidationUtility::ensureNullOrArrayOfType(
            '$attributes', $attributes, __NAMESPACE__ . '\Pair');

        $this->attributes = $attributes;

        return $this;
    }
652847
public function newModelInstance($attributes = [])
    {
        return \tap(parent::newModelInstance($attributes), function ($model) {
            $model->setTenantor($this->tenantor);
        });
    }
327126
protected function expandAttributes(array $attributes)
    {
        foreach ($attributes as &$attribute) {
            if (is_callable($attribute) && ! is_string($attribute) && ! is_array($attribute)) {
                $attribute = $attribute($attributes);
            }

            if ($attribute instanceof static) {
                $attribute = $attribute->create()->getKey();
            }

            if ($attribute instanceof Model) {
                $attribute = $attribute->getKey();
            }
        }

        return $attributes;
    }
935405
public function create(array $attributes)
    {
        $this->applyAncestor();
        $this->applyCriteria();
        $this->applyScope();

        $model = $this->model->create($attributes);

        $model->save();

        $this->applyAfterSave($model);
        $this->resetModel();

        event(new RepositoryEntityCreated($this, $model));

        return $this->parserResult($model);
    }
359708
public function _setAttributes($attributes)
    {
        if (is_array($attributes)) {
            foreach ($attributes as $attribute => $value) {
                $this->{$attribute} = $value;
            }

            return $this;
        }

        //@todo: put real exception here cos exception' gon be thrown either ways, so put one that makes sense
        //or something else that has more meaning
        throw new \InvalidArgumentException('Invalid argument Passed to set attributes on object');
    }
1312342
public function withAttributes(array $attributes)
    {
        $this->attributes = $this->immutable + $attributes + $this->attributes;

        return $this;
    }
195186
public function create(array $attributes)
    {
        $instance = $this->related->newInstance($attributes);

        $this->setForeignAttributesForCreate($instance);

        $instance->save();

        return $instance;
    }
781140
public function update(array $attributes)
    {
        if ($this->related->usesTimestamps()) {
            $attributes[$this->relatedUpdatedAt()] = $this->related->freshTimestamp();
        }

        return $this->query->update($attributes);
    }
1080337
public function set($attributes = array())
    {
        $this->attributes = array_replace_recursive($this->attributes, $attributes);

        return $this->attributes;
    }
581801
protected function prepareAttributes($attributes)
    {
        foreach($this->getAttributeConfig() as $attr => $config){

            // If the attribute is not defined in model or $attributes array
            // set the default value.
            if(!isset($this->attributes[$attr]) && !isset($attributes[$attr])){

                $attributes[$attr] = $config['default'];

            }

        }

        foreach($attributes as $key => $value){

            if(isset($this->config['attributes'][$key])){

                $attributes[$key] = $this->$key()->before_save($value);

            } elseif(isset($this->config['relationships'][$key])){

                unset($attributes[$key]);

                $relationship = $this->config['relationships'][$key];

                $this->translateShorthand($value);

                switch($relationship['type']){

                    case Relationship::HAS_PIVOT:

                        if($value instanceof Collection) $value = $value->all();

                        if($value instanceof EntityContract) $value = [$value];

                        $this->$key()->saveMany($value);

                        break;

                    case Relationship::HAS_MANY:

                        $this->$key()->saveMany((array)$value);

                        break;

                    case Relationship::BELONGS_TO:

                        $this->$key()->associate($value);

                        break;

                    case Relationship::HAS_ONE:

                        $this->$key()->save($value);

                        break;

                    default:

                        throw new \Exception(sprintf(
                            "Unknown relationship type \"%s\" on entity \"%s\"",
                            $relationship['type'],
                            $relationship['entity']
                        ));

                        break;
                }

            }

        }

        return $attributes;
    }
1072925
public function withAttributes(array $attributes = []): Element
    {
        $this->attributes = array_merge(
            $this->attributes,
            $attributes
        );

        return $this;
    }
445386
public function forceCreate(array $attributes)
    {
        return $this->model->unguarded(function () use ($attributes) {
            return $this->newModelInstance()->create($attributes);
        });
    }