Skip to content

Commit

Permalink
Fix aggregation alias
Browse files Browse the repository at this point in the history
  • Loading branch information
GromNaN committed Jan 29, 2025
1 parent 1d4699e commit 42053d0
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/Eloquent/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ public function withAggregate($relations, $column, $function = null)

$alias = match (true) {
count($segments) === 1 => Str::snake($segments[0]) . '_' . $function,
count($segments) === 3 && Str::lower($segments[1]) => $segments[2],
count($segments) === 3 && Str::lower($segments[1]) === 'as' => $segments[2],
default => throw new InvalidArgumentException(sprintf('Invalid relation name format. Expected "relation as alias" or "relation", got "%s"', $name)),
};
$name = $segments[0];
Expand Down Expand Up @@ -413,7 +413,7 @@ public function eagerLoadRelations(array $models)
$model->setAttribute($withAggregate['alias'], $value);
}
} else {
throw new RuntimeException(sprintf('Unsupported relation type for aggregation', $withAggregate['relation']::class));
throw new RuntimeException(sprintf('Unsupported relation type for aggregation: %s', $withAggregate['relation']::class));
}
}
}
Expand Down
40 changes: 40 additions & 0 deletions tests/Eloquent/EloquentWithAggregateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use MongoDB\Laravel\Tests\Eloquent\Models\EloquentWithAggregateModel3;
use MongoDB\Laravel\Tests\Eloquent\Models\EloquentWithAggregateModel4;
use MongoDB\Laravel\Tests\TestCase;
use PHPUnit\Framework\Attributes\TestWith;

use function count;
use function ksort;
Expand Down Expand Up @@ -55,6 +56,45 @@ public function testWithAggregate()
], $results->get());
}

public function testWithAggregateAlias()
{
EloquentWithAggregateModel1::create(['id' => 1]);
$one = EloquentWithAggregateModel1::create(['id' => 2]);
$one->twos()->create(['value' => 4]);
$one->twos()->create(['value' => 6]);

$results = EloquentWithAggregateModel1::withCount('twos as result')->where('id', 2);
self::assertSameResults([
['id' => 2, 'result' => 2],
], $results->get());

$results = EloquentWithAggregateModel1::withMax('twos as result', 'value')->where('id', 2);
self::assertSameResults([
['id' => 2, 'result' => 6],
], $results->get());

$results = EloquentWithAggregateModel1::withMin('twos as result', 'value')->where('id', 2);
self::assertSameResults([
['id' => 2, 'result' => 4],
], $results->get());

$results = EloquentWithAggregateModel1::withAvg('twos as result', 'value')->where('id', 2);
self::assertSameResults([
['id' => 2, 'result' => 5.0],
], $results->get());
}

#[TestWith(['withCount'])]
#[TestWith(['withMax'])]
#[TestWith(['withMin'])]
#[TestWith(['withAvg'])]
public function testWithAggregateInvalidAlias(string $method)
{
self::expectException(InvalidArgumentException::class);
self::expectExceptionMessage('Expected "relation as alias" or "relation", got "twos foo result"');
EloquentWithAggregateModel1::{$method}('twos foo result', 'value')->get();
}

public function testWithAggregateEmbed()
{
EloquentWithAggregateModel1::create(['id' => 1]);
Expand Down

0 comments on commit 42053d0

Please sign in to comment.