diff --git a/src/Relations/BelongsToLevel.php b/src/Relations/BelongsToLevel.php new file mode 100644 index 0000000..3b0d6df --- /dev/null +++ b/src/Relations/BelongsToLevel.php @@ -0,0 +1,62 @@ +level = $level; + $this->relationName = $relationName; + + parent::__construct($query, $parent); + } + + public function addConstraints() + { + $this->query->ancestorByLevel($this->level); + } + + public function addEagerConstraints(array $models) + { + $this->query->ancestorByLevel($this->level); + } + + public function initRelation(array $models, $relation) + { + foreach ($models as $model) { + $model->setRelation($relation, $this->getDefaultFor($model)); + } + + return $models; + } + + public function match(array $models, Collection $results, $relation) + { + return $models; + } + + public function getResults() + { + return $this->query->first(); + } + + protected function newRelatedInstanceFor(Model $parent) + { + return $this->related->newInstance(); + } +} diff --git a/src/Traits/HasTreeRelationships.php b/src/Traits/HasTreeRelationships.php new file mode 100644 index 0000000..ed56970 --- /dev/null +++ b/src/Traits/HasTreeRelationships.php @@ -0,0 +1,28 @@ +guessBelongsToRelation(); + } + + $instance = $instance ?: $this->newRelatedInstance($related); + + return new BelongsToLevel($instance->newQuery(), $this, $level, $relation); + } +} diff --git a/src/Traits/LTreeModelTrait.php b/src/Traits/LTreeModelTrait.php index e74d643..76f5865 100644 --- a/src/Traits/LTreeModelTrait.php +++ b/src/Traits/LTreeModelTrait.php @@ -112,10 +112,15 @@ public function renderAsLtree($value, $pad_string = LTreeHelper::PAD_STRING, $pa public function getAncestorByLevel(int $level = 1) { - return static::whereRaw(sprintf( - "({$this->getLtreePathColumn()} @> text2ltree('%s')) and nlevel(path) = %d", + return static::scopeAncestorByLevel($level)->first(); + } + + public function scopeAncestorByLevel(Builder $query, int $level = 1): Builder + { + return $query->whereRaw(sprintf( + "({$this->getLtreePathColumn()} @> text2ltree('%s')) and nlevel(path) = %d", LTreeHelper::pathAsString($this->getLtreePath()), $level) - )->first(); + ); } }