From 571f09c4b23c349cb1a5db8bb88af291ed30389c Mon Sep 17 00:00:00 2001 From: Alexandru Bucur Date: Tue, 19 Mar 2024 23:45:47 +0100 Subject: [PATCH] fix: allow non nested joins to specify pivot information (#173) --- src/Mixins/JoinRelationship.php | 23 +++++++++++++++-------- tests/JoinRelationshipTest.php | 29 +++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/Mixins/JoinRelationship.php b/src/Mixins/JoinRelationship.php index 4008025..95e2f76 100644 --- a/src/Mixins/JoinRelationship.php +++ b/src/Mixins/JoinRelationship.php @@ -115,6 +115,11 @@ public function joinRelationship(): Closure return $this; } + $relationCallback = $callback; + if ($callback && is_array($callback) && isset($callback[$relationName]) && is_array($callback[$relationName])) { + $relationCallback = $callback[$relationName]; + } + $relation = $this->getModel()->{$relationName}(); $relationQuery = $relation->getQuery(); $alias = $joinHelper->getAliasName( @@ -122,7 +127,7 @@ public function joinRelationship(): Closure $relation, $relationName, $relationQuery->getModel()->getTable(), - $callback + $relationCallback ); if ($relation instanceof BelongsToMany && !is_array($alias)) { @@ -131,12 +136,13 @@ public function joinRelationship(): Closure $relation, $relationName, $relation->getTable(), - $callback + $relationCallback ); $alias = [$extraAlias, $alias]; } $aliasString = is_array($alias) ? implode('.', $alias) : $alias; + $useAlias = $alias ? true : $useAlias; $relationJoinCache = $alias ? "{$aliasString}.{$relationQuery->getModel()->getTable()}.{$relationName}" @@ -146,6 +152,9 @@ public function joinRelationship(): Closure return $this; } + if ($useAlias) { + StaticCache::setTableAliasForModel($relation->getModel(), $alias); + } $joinHelper->markRelationshipAsAlreadyJoined($this->getModel(), $relationJoinCache); StaticCache::clear(); @@ -153,14 +162,13 @@ public function joinRelationship(): Closure $relation->performJoinForEloquentPowerJoins( builder: $this, joinType: $joinType, - callback: $callback, + callback: $relationCallback, alias: $alias, disableExtraConditions: $disableExtraConditions, morphable: $morphable, ); return $this; - }; } @@ -353,7 +361,8 @@ public function orderByPowerJoins(): Closure }, $this->getModel()); if ($aggregation) { - $aliasName = sprintf('%s_%s_%s', + $aliasName = sprintf( + '%s_%s_%s', $latestRelationshipModel->getTable(), $column, $aggregation @@ -382,7 +391,6 @@ public function orderByPowerJoins(): Closure } return $this; }; - } public function orderByLeftPowerJoins(): Closure @@ -517,7 +525,7 @@ public function hasNestedUsingJoins(): Closure foreach ($relations as $index => $relation) { $relationName = $relation; - if (! $latestRelation) { + if (!$latestRelation) { $relation = $this->getRelationWithoutConstraintsProxy($relation); } else { $relation = $latestRelation->getModel()->query()->getRelationWithoutConstraintsProxy($relation); @@ -540,7 +548,6 @@ public function powerJoinDoesntHave(): Closure return function ($relation, $boolean = 'and', Closure $callback = null) { return $this->powerJoinHas($relation, '<', 1, $boolean, $callback); }; - } public function powerJoinWhereHas(): Closure diff --git a/tests/JoinRelationshipTest.php b/tests/JoinRelationshipTest.php index f26916c..ad0bbbc 100644 --- a/tests/JoinRelationshipTest.php +++ b/tests/JoinRelationshipTest.php @@ -537,8 +537,8 @@ public function test_join_has_many_through_relationship_with_alias() { $query = User::joinRelationship('commentsThroughPosts.user', [ 'commentsThroughPosts' => [ - 'posts' => fn($join) => $join->as('posts_alias'), - 'comments' => fn($join) => $join->as('comments_alias'), + 'posts' => fn ($join) => $join->as('posts_alias'), + 'comments' => fn ($join) => $join->as('comments_alias'), ], ])->toSql(); @@ -558,8 +558,8 @@ public function test_join_belongs_to_many_relationship_with_alias() { $query = Group::joinRelationship('posts.user', [ 'posts' => [ - 'posts' => fn($join) => $join->as('posts_alias'), - 'post_groups' => fn($join) => $join->as('post_groups_alias'), + 'posts' => fn ($join) => $join->as('posts_alias'), + 'post_groups' => fn ($join) => $join->as('post_groups_alias'), ], ])->toSql(); @@ -574,6 +574,27 @@ public function test_join_belongs_to_many_relationship_with_alias() ); } + /** @test */ + public function test_join_belongs_to_many_with_alias() + { + $query = Group::joinRelationship('posts', [ + 'posts' => [ + 'posts' => fn ($join) => $join->as('posts_alias'), + 'post_groups' => fn ($join) => $join->as('post_groups_not_nested'), + ], + ])->toSql(); + + $this->assertStringContainsString( + 'inner join "posts" as "posts_alias"', + $query + ); + + $this->assertStringContainsString( + 'inner join "post_groups" as "post_groups_not_nested"', + $query + ); + } + /** @test */ public function test_it_joins_different_tables_with_same_relationship_name() {