Last active
January 28, 2020 19:21
-
-
Save kmuenkel/dcc6cd0da9b2c1928c1c753f88be31a6 to your computer and use it in GitHub Desktop.
Link any two models according to the nature of the specified parent Model relation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Illuminate\Database\Eloquent\Model; | |
use Illuminate\Database\Eloquent\Relations; | |
use Illuminate\Database\Eloquent\Collection as EloquentCollection; | |
if (!function_exists('relate_models')) { | |
/** | |
* @param Model $model | |
* @param Model $relatedModel | |
* @param string $relationName | |
* @param bool $suppressEvents | |
*/ | |
function relate_models(Model $model, Model $relatedModel, $relationName, $suppressEvents = true) | |
{ | |
/** @var Relations\Relation $relation */ | |
$relation = $model->$relationName(); | |
$expectedModel = $relation->getModel(); | |
if (!($relatedModel instanceof $expectedModel)) { | |
$relation = get_class($model)."::$relationName()"; | |
$expectedModel = get_class($expectedModel); | |
$givenModel = get_class($relatedModel); | |
throw new InvalidArgumentException("$relation expects the related model to be a $expectedModel." | |
." $givenModel given." | |
); | |
} | |
$save = function (Model $model) { | |
return function () use ($model) { | |
$model::unguarded(function () use ($model) { | |
$model->save(); | |
}); | |
}; | |
}; | |
if ($relation instanceof Relations\BelongsTo) { | |
$relation->associate($relatedModel); | |
$suppressEvents ? $model::withoutEvents($save($model)) : $save($model); | |
} elseif ($relation instanceof Relations\HasOneOrMany) { | |
$foreignKeyName = $relation->getForeignKeyName(); | |
$localKeyName = $relation->getLocalKeyName(); | |
$localKey = $model->getAttribute($localKeyName); | |
$relatedModel->$foreignKeyName = $localKey; | |
if ($relation instanceof Relations\MorphOneOrMany) { | |
$morphTypeField = $relation->getMorphType(); | |
$morphType = $relation->getMorphClass(); | |
$relatedModel->$morphTypeField = $morphType; | |
} | |
$suppressEvents ? $relatedModel::withoutEvents($save($relatedModel)) : $save($relatedModel); | |
$relationship = ($relation instanceof Relations\HasMany || $relation instanceof Relations\MorphMany) ? | |
app(EloquentCollection::class, ['items' => [$relatedModel]]) : $relatedModel; | |
$model->setRelation($relationName, $relationship); | |
} elseif ($relation instanceof Relations\BelongsToMany) { | |
$relation->attach($relatedModel); | |
} else { | |
throw new InvalidArgumentException('Unsupported relation type ' . get_class($relation)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment