Skip to content

Commit

Permalink
Support HasOneDeep relationships
Browse files Browse the repository at this point in the history
  • Loading branch information
staudenmeir committed Jun 20, 2023
1 parent 82db6aa commit 0f599fc
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 7 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"barryvdh/laravel-ide-helper": "^2.12",
"mockery/mockery": "^1.5",
"nesbot/carbon": "^2.62.1",
"staudenmeir/eloquent-has-many-deep": "^1.17"
"staudenmeir/eloquent-has-many-deep": "^1.17.2"
},
"suggest": {
"barryvdh/laravel-ide-helper": "Provide type hints for attributes and relations."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,15 @@ public function addEagerConstraintsToDeepRelationship(Builder $query, array $mod
* @param array $models
* @param \Illuminate\Database\Eloquent\Collection $results
* @param string $relation
* @param string $type
* @return array
*/
public function matchResultsForDeepRelationship(array $models, Collection $results, string $relation): array
{
public function matchResultsForDeepRelationship(
array $models,
Collection $results,
string $relation,
string $type = 'many'
): array {
$dictionary = $this->buildDictionaryForDeepRelationship($results);

$attribute = $this->andSelf ? $this->localKey : $this->getForeignKeyName();
Expand All @@ -42,7 +47,9 @@ public function matchResultsForDeepRelationship(array $models, Collection $resul
$key = $model->$attribute;

if (isset($dictionary[$key])) {
$value = $this->related->newCollection($dictionary[$key]);
$value = $dictionary[$key];

$value = $type === 'one' ? reset($value) : $this->related->newCollection($value);

$model->setRelation($relation, $value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,24 @@ public function addEagerConstraintsToDeepRelationship(Builder $query, array $mod
* @param array $models
* @param \Illuminate\Database\Eloquent\Collection $results
* @param string $relation
* @param string $type
* @return array
*/
public function matchResultsForDeepRelationship(array $models, Collection $results, string $relation): array
{
public function matchResultsForDeepRelationship(
array $models,
Collection $results,
string $relation,
string $type = 'many'
): array {
$dictionary = $this->buildDictionaryForDeepRelationship($results);

foreach ($models as $model) {
$key = $model->{$this->localKey};

if (isset($dictionary[$key])) {
$value = $this->related->newCollection($dictionary[$key]);
$value = $dictionary[$key];

$value = $type === 'one' ? reset($value) : $this->related->newCollection($value);

$model->setRelation($relation, $value);
}
Expand Down
12 changes: 12 additions & 0 deletions tests/Tree/Concatenation/AncestorsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ public function testEagerLoadingAndSelf()
$this->assertEquals([100, 110], $users[10]->ancestorAndSelfPosts->pluck('id')->all());
}

public function testEagerLoadingWithHasOneDeep()
{
$users = User::with([
'ancestorPost' => fn (HasManyDeep $query) => $query->orderBy('id'),
])->get();

$this->assertNull($users[0]->ancestorPost);
$this->assertEquals(10, $users[1]->ancestorPost->id);
$this->assertEquals(10, $users[7]->ancestorPost->id);
$this->assertNull($users[10]->ancestorPost);
}

public function testLazyEagerLoading()
{
$users = User::all()->load([
Expand Down
10 changes: 10 additions & 0 deletions tests/Tree/Concatenation/DescendantsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ public function testEagerLoadingAndSelf()
$this->assertEquals([100, 110], $users[9]->descendantPostsAndSelf->pluck('id')->all());
}

public function testEagerLoadingWithHasOneDeep()
{
$users = User::with('descendantPost')->get();

$this->assertEquals(20, $users[0]->descendantPost->id);
$this->assertEquals(50, $users[1]->descendantPost->id);
$this->assertNull($users[8]->descendantPost);
$this->assertEquals(100, $users[9]->descendantPost->id);
}

public function testLazyEagerLoading()
{
$users = User::all()->load('descendantPosts');
Expand Down
17 changes: 17 additions & 0 deletions tests/Tree/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Staudenmeir\EloquentHasManyDeep\HasManyDeep;
use Staudenmeir\EloquentHasManyDeep\HasOneDeep;
use Staudenmeir\EloquentHasManyDeep\HasRelationships;
use Staudenmeir\EloquentHasManyDeep\HasTableAlias;
use Staudenmeir\LaravelAdjacencyList\Eloquent\HasRecursiveRelationships;
Expand Down Expand Up @@ -38,6 +39,14 @@ public function getCustomPaths()
);
}

public function ancestorPost(): HasOneDeep
{
return $this->hasOneDeepFromRelations(
$this->ancestors(),
(new static())->hasMany(Post::class)
);
}

public function ancestorPosts(): HasManyDeep
{
return $this->hasManyDeepFromRelations(
Expand All @@ -62,6 +71,14 @@ public function bloodlinePosts(): HasManyDeep
);
}

public function descendantPost(): HasOneDeep
{
return $this->hasOneDeepFromRelations(
$this->descendants(),
(new static())->hasMany(Post::class)
);
}

public function descendantPosts(): HasManyDeep
{
return $this->hasManyDeepFromRelations(
Expand Down

0 comments on commit 0f599fc

Please sign in to comment.