diff --git a/composer.json b/composer.json index 8517aba..c1277c7 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ }, "require-dev": { "phpunit/phpunit": "^10.1", - "staudenmeir/eloquent-has-many-deep": "^1.18" + "staudenmeir/eloquent-has-many-deep": "^1.18.1" }, "autoload": { "psr-4": { diff --git a/src/Relations/Traits/Concatenation/IsConcatenableBelongsToJsonRelation.php b/src/Relations/Traits/Concatenation/IsConcatenableBelongsToJsonRelation.php index dd94793..237448b 100644 --- a/src/Relations/Traits/Concatenation/IsConcatenableBelongsToJsonRelation.php +++ b/src/Relations/Traits/Concatenation/IsConcatenableBelongsToJsonRelation.php @@ -58,10 +58,15 @@ public function appendToDeepRelationship(array $through, array $foreignKeys, arr * @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) { @@ -73,9 +78,11 @@ public function matchResultsForDeepRelationship(array $models, Collection $resul } } - $collection = $this->related->newCollection($matches); + $value = $type === 'one' + ? (reset($matches) ?: null) + : $this->related->newCollection($matches); - $model->setRelation($relation, $collection); + $model->setRelation($relation, $value); } return $models; diff --git a/src/Relations/Traits/Concatenation/IsConcatenableHasManyJsonRelation.php b/src/Relations/Traits/Concatenation/IsConcatenableHasManyJsonRelation.php index eb27c52..6cfbf53 100644 --- a/src/Relations/Traits/Concatenation/IsConcatenableHasManyJsonRelation.php +++ b/src/Relations/Traits/Concatenation/IsConcatenableHasManyJsonRelation.php @@ -74,19 +74,28 @@ public function getThroughKeyForDeepRelationships(string $alias): Expression * @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 = $this->getDictionaryKey($model->{$this->localKey}); if (isset($dictionary[$key])) { - $collection = $this->related->newCollection($dictionary[$key]); + $value = $dictionary[$key]; + + $value = $type === 'one' + ? (reset($value) ?: null) + : $this->related->newCollection($value); - $model->setRelation($relation, $collection); + $model->setRelation($relation, $value); } } diff --git a/tests/Concatenation/BelongsToJson/FirstPositionTest.php b/tests/Concatenation/BelongsToJson/FirstPositionTest.php index e8791a5..fddf847 100644 --- a/tests/Concatenation/BelongsToJson/FirstPositionTest.php +++ b/tests/Concatenation/BelongsToJson/FirstPositionTest.php @@ -40,6 +40,15 @@ public function testEagerLoading() $this->assertEquals([83, 84], $users[2]->permissions->pluck('id')->all()); } + public function testEagerLoadingWithHasOneDeep() + { + $users = User::with('permission')->get(); + + $this->assertEquals(81, $users[0]->permission->id); + $this->assertNull($users[1]->permission); + $this->assertEquals(83, $users[2]->permission->id); + } + public function testEagerLoadingWithObjects() { $users = User::with('permissions2')->get(); diff --git a/tests/Concatenation/HasManyJson/FirstPositionTest.php b/tests/Concatenation/HasManyJson/FirstPositionTest.php index 0e6f73a..3635ed9 100644 --- a/tests/Concatenation/HasManyJson/FirstPositionTest.php +++ b/tests/Concatenation/HasManyJson/FirstPositionTest.php @@ -57,6 +57,15 @@ public function testEagerLoadingWithObjects() $this->assertEquals([], $roles[3]->countries2->pluck('id')->all()); } + public function testEagerLoadingWithHasOneDeep() + { + $roles = Role::with('country')->get(); + + $this->assertEquals(71, $roles[0]->country->id); + $this->assertEquals(71, $roles[1]->country->id); + $this->assertNull($roles[3]->country); + } + public function testLazyEagerLoading() { $roles = Role::all()->load('countries'); diff --git a/tests/Models/Role.php b/tests/Models/Role.php index 21b3937..ca1b00d 100644 --- a/tests/Models/Role.php +++ b/tests/Models/Role.php @@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany; use Staudenmeir\EloquentHasManyDeep\HasManyDeep; +use Staudenmeir\EloquentHasManyDeep\HasOneDeep; use Staudenmeir\EloquentHasManyDeep\HasRelationships; use Staudenmeir\EloquentJsonRelations\JsonKey; use Staudenmeir\EloquentJsonRelations\Relations\HasManyJson; @@ -22,6 +23,11 @@ public function countries2(): HasManyDeep return $this->hasManyDeepFromRelations($this->usersWithObjects(), (new User())->country()); } + public function country(): HasOneDeep + { + return $this->hasOneDeepFromRelations($this->users(), (new User())->country()); + } + public function permissions(): HasMany { return $this->hasMany(Permission::class); diff --git a/tests/Models/User.php b/tests/Models/User.php index f357564..2edaf39 100644 --- a/tests/Models/User.php +++ b/tests/Models/User.php @@ -6,6 +6,7 @@ use Illuminate\Database\Eloquent\Relations\HasManyThrough; use Illuminate\Database\Eloquent\Relations\HasOneThrough; use Staudenmeir\EloquentHasManyDeep\HasManyDeep; +use Staudenmeir\EloquentHasManyDeep\HasOneDeep; use Staudenmeir\EloquentHasManyDeep\HasRelationships; use Staudenmeir\EloquentJsonRelations\Relations\BelongsToJson; @@ -29,6 +30,11 @@ public function locale(): BelongsTo return $this->belongsTo(Locale::class, 'options->locale_id'); } + public function permission(): HasOneDeep + { + return $this->hasOneDeepFromRelations($this->roles(), (new Role())->permissions()); + } + public function permissions(): HasManyDeep { return $this->hasManyDeepFromRelations($this->roles(), (new Role())->permissions());