Skip to content

Commit

Permalink
Add additional methods (#232)
Browse files Browse the repository at this point in the history
  • Loading branch information
staudenmeir committed Apr 22, 2024
1 parent a496423 commit 053c37d
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 0 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ Supports Laravel 5.5+.
- [Custom Paths](#custom-paths)
- [Nested Results](#nested-results)
- [Initial & Recursive Query Constraints](#initial--recursive-query-constraints)
- [Additional Methods](#additional-methods)
- [Custom Relationships](#custom-relationships)
- [Deep Relationship Concatenation](#deep-relationship-concatenation)
- [Known Issues](#known-issues)
Expand Down Expand Up @@ -407,6 +408,24 @@ $tree = User::withQueryConstraint(function (Builder $query) {
You can also add a custom constraint to only the initial or recursive query using `withInitialQueryConstraint()`/
`withRecursiveQueryConstraint()`.

#### Additional Methods

The trait also provides methods to check relationships between models:

- `isChildOf(Model $model)`: Checks if the current model is a child of the given model.
- `isParentOf(Model $model)`: Checks if the current model is a parent of the given model.
- `getDepthRelatedTo(Model $model)`: Returns the depth of the current model related to the given model.

```php
$rootUser = User::create(['parent_id' => null]);
$firstLevelUser = User::create(['parent_id' => $rootUser->id]);
$secondLevelUser = User::create(['parent_id' => $firstLevelUser->id]);

$isChildOf = $secondLevelUser->isChildOf($firstLevelUser); // Output: true
$isParentOf = $rootUser->isParentOf($firstLevelUser); // Output: true
$depthRelatedTo = $secondLevelUser->getDepthRelatedTo($rootUser); // Output: 2
```

#### Custom Relationships

You can also define custom relationships to retrieve related models recursively.
Expand Down
1 change: 1 addition & 0 deletions src/Eloquent/Traits/HasAdjacencyList.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ trait HasAdjacencyList
{
use HasOfDescendantsRelationships;
use HasQueryConstraints;
use HasRecursiveRelationshipHelpers;
use HasRecursiveRelationshipScopes;

/**
Expand Down
50 changes: 50 additions & 0 deletions src/Eloquent/Traits/HasRecursiveRelationshipHelpers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace Staudenmeir\LaravelAdjacencyList\Eloquent\Traits;

use Illuminate\Database\Eloquent\Model;

trait HasRecursiveRelationshipHelpers
{
/**
* Determine if the model is a child of the given model.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return bool
*/
public function isChildOf(Model $model): bool
{
return $this->parent ? $this->parent->is($model) : false;
}

/**
* Determine if the model is the parent of the given model.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return bool
*/
public function isParentOf(Model $model): bool
{
return $this->children->contains($model);
}

/**
* Get the depth of the model related to the given model.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return int|null
*/
public function getDepthRelatedTo(Model $model): ?int
{
$thisModel = $this->bloodline->find($this);
$relatedModel = $this->bloodline->find($model);

if ($thisModel && $relatedModel) {
$depthName = $this->getDepthName();

return $thisModel->$depthName - $relatedModel->$depthName;
}

return null;
}
}
21 changes: 21 additions & 0 deletions tests/Tree/EloquentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,27 @@ public function testScopeDepthFirstWithStringKey()
$this->assertEquals(['a', 'b', 'c', 'd'], $categories->pluck('id')->all());
}

public function testIsChildOf()
{
$this->assertTrue(User::find(5)->isChildOf(User::find(2)));
$this->assertFalse(User::find(5)->isChildOf(User::find(1)));
$this->assertFalse(User::find(1)->isChildOf(User::find(2)));
}

public function testIsParentOf()
{
$this->assertTrue(User::find(2)->isParentOf(User::find(5)));
$this->assertFalse(User::find(1)->isParentOf(User::find(5)));
$this->assertFalse(User::find(2)->isParentOf(User::find(1)));
}

public function testGetDepthRelatedTo()
{
$this->assertEquals(2, User::find(5)->getDepthRelatedTo(User::find(1)));
$this->assertEquals(-2, User::find(1)->getDepthRelatedTo(User::find(5)));
$this->assertNull(User::find(4)->getDepthRelatedTo(User::find(5)));
}

public function testWithInitialQueryConstraint()
{
$users = User::withInitialQueryConstraint(function (Builder $query) {
Expand Down

0 comments on commit 053c37d

Please sign in to comment.