Skip to content

Commit

Permalink
staudenmeir#259: Added method to load in relations.
Browse files Browse the repository at this point in the history
  • Loading branch information
tylernathanreed committed Sep 5, 2024
1 parent 3bdb2b2 commit 69e2ba9
Showing 1 changed file with 55 additions and 0 deletions.
55 changes: 55 additions & 0 deletions src/Eloquent/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,59 @@ public function toTree($childrenRelation = 'children')

return $tree;
}

/**
* Load parent/anscestor relations already present in the tree.
*
* @return static<int, TModel>
*/
public function loadTreePathRelations()
{
$instance = $this->first();

if (is_null($instance)) {
return $this;
}

if (! method_exists($instance, 'getPathName') || ! method_exists($instance, 'getPathSeparator')) {
throw new RuntimeException(sprintf(
'Model [%s] is not have recusive relations.',
$instance::class,
));
}

$keyName = $instance->getKeyName();
$pathName = $instance->getPathName();
$pathSeparator = $instance->getPathSeparator();

$lookup = $this->keyBy($keyName);

$keys = $this
->pluck($pathName)
->flatMap(fn (string $path): array => explode($pathSeparator, $path))
->unique()
->values();

$missing = $keys->diff($lookup->modelKeys());

if ($missing->isNotEmpty()) {
$lookup->merge($instance->newQuery()->findMany($missing)->keyBy($keyName));
}

foreach ($this->all() as $model) {
$path = array_reverse(explode($pathSeparator, $model->getAttribute($pathName)));

$ancestorsAndSelf = array_reduce(
$path,
fn ($collection, $step) => $collection->push($lookup[$step] ?? null),
$instance->newCollection(),
);

$model->setRelation('parent', count($path) > 1 ? $lookup[$path[1]] : null);
$model->setRelation('ancestorsAndSelf', $ancestorsAndSelf);
$model->setRelation('ancestors', $ancestorsAndSelf->slice(0, -1));
}

return $this;
}
}

0 comments on commit 69e2ba9

Please sign in to comment.