Skip to content

Commit

Permalink
Added belongs to level via relation (#13)
Browse files Browse the repository at this point in the history
* add belongs to level via relation
  • Loading branch information
pvsaintpe authored Oct 23, 2019
1 parent 1e23359 commit 3efe7b0
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 3 deletions.
62 changes: 62 additions & 0 deletions src/Relations/BelongsToLevel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

declare(strict_types=1);

namespace Umbrellio\LTree\Relations;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Concerns\SupportsDefaultModels;
use Illuminate\Database\Eloquent\Relations\Relation;

class BelongsToLevel extends Relation
{
use SupportsDefaultModels;

protected $level;

protected $relationName;

public function __construct(Builder $query, Model $parent, int $level, $relationName)
{
$this->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();
}
}
28 changes: 28 additions & 0 deletions src/Traits/HasTreeRelationships.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Umbrellio\LTree\Traits;

use Illuminate\Database\Eloquent\Concerns\HasRelationships;
use Illuminate\Database\Eloquent\Model;
use Umbrellio\LTree\Relations\BelongsToLevel;

/**
* @mixin HasRelationships
* @mixin LTreeModelTrait
* @mixin Model
*/
trait HasTreeRelationships
{
protected function belongsToLevel($related, int $level = 1, ?Model $instance = null, ?string $relation = null)
{
if ($relation === null) {
$relation = $this->guessBelongsToRelation();
}

$instance = $instance ?: $this->newRelatedInstance($related);

return new BelongsToLevel($instance->newQuery(), $this, $level, $relation);
}
}
11 changes: 8 additions & 3 deletions src/Traits/LTreeModelTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
);
}
}

0 comments on commit 3efe7b0

Please sign in to comment.