Skip to content

Commit b9aa4c2

Browse files
Runig006Alex Osendi
andauthored
Fix nested many to many alias, allow callbacks using the full relation name (#127)
* Fix many to many nested * check with dots if is already replaced --------- Co-authored-by: Alex Osendi <[email protected]>
1 parent 6b31235 commit b9aa4c2

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

src/PowerJoinClause.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ protected function useTableAliasInConditions(): self
114114
$table = $this->tableName;
115115

116116
// if it was already replaced, skip
117-
if (Str::startsWith($where['first'] . '.', $this->alias) || Str::startsWith($where['second'] . '.', $this->alias)) {
117+
if (Str::startsWith($where['first'] . '.', $this->alias . '.') || Str::startsWith($where['second'] . '.', $this->alias . '.')) {
118118
return $where;
119119
}
120120

src/PowerJoins.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ public function scopeJoinRelationship(Builder $query, $relationName, $callback =
4444

4545
if (Str::contains($relationName, '.')) {
4646
$query->joinNestedRelationship($relationName, $callback, $joinType, $useAlias, $disableExtraConditions);
47-
4847
return;
4948
}
5049

@@ -138,7 +137,11 @@ public function scopeJoinNestedRelationship(Builder $query, string $relationship
138137
/** @var \Illuminate\Database\Eloquent\Relations\Relation */
139138
$latestRelation = null;
140139

140+
$part = [];
141141
foreach ($relations as $relationName) {
142+
$part[] = $relationName;
143+
$fullRelationName = join(".", $part);
144+
142145
$currentModel = $latestRelation ? $latestRelation->getModel() : $query->getModel();
143146
$relation = $currentModel->{$relationName}();
144147
$relationCallback = null;
@@ -147,7 +150,16 @@ public function scopeJoinNestedRelationship(Builder $query, string $relationship
147150
$relationCallback = $callback[$relationName];
148151
}
149152

153+
if ($callback && is_array($callback) && isset($callback[$fullRelationName])) {
154+
$relationCallback = $callback[$fullRelationName];
155+
}
156+
150157
$alias = $this->getAliasName($useAlias, $relation, $relationName, $relation->getQuery()->getModel()->getTable(), $relationCallback);
158+
if ($alias && $relation instanceof BelongsToMany && ! is_array($alias)) {
159+
$extraAlias = $this->getAliasName($useAlias, $relation, $relationName, $relation->getTable(), $relationCallback);
160+
$alias = [$extraAlias, $alias];
161+
}
162+
151163
$aliasString = is_array($alias) ? implode('.', $alias) : $alias;
152164
$useAlias = $alias ? true : $useAlias;
153165

tests/JoinRelationshipUsingAliasTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,4 +227,25 @@ public function test_joining_deep_relation_using_same_base_table()
227227

228228
$this->assertStringContainsString('inner join "categories" as "categories_alias" on "post_alias"."category_id" = "categories_alias"."id"', $sql);
229229
}
230+
231+
/** @test */
232+
public function test_joining_deep_many_to_many_relation_using_same_base_table()
233+
{
234+
$alias = [
235+
'groups' => function ($join) {
236+
$join->as('groups_alias');
237+
},
238+
'posts' => [
239+
'post_groups' => function ($join) {
240+
$join->as('post_groups_alias');
241+
},
242+
'posts' => function ($join) {
243+
$join->as('post_alias');
244+
},
245+
]
246+
];
247+
$query = User::joinRelationship('groups', $alias)->joinRelationship('groups.posts', $alias);
248+
$sql = $query->toSql();
249+
$this->assertStringContainsString('inner join "posts" as "post_alias" on "post_alias"."id" = "post_groups_alias"."post_id"', $sql);
250+
}
230251
}

0 commit comments

Comments
 (0)