-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PHPORM-238 Add support for withCount
and other aggregations
#3182
base: 5.x
Are you sure you want to change the base?
Conversation
tests/QueryBuilderTest.php
Outdated
$this->assertFalse(DB::table('items')->where('name', 'ladle')->exists()); | ||
$this->assertFalse(DB::table('items')->doesntExist()); | ||
$this->assertFalse(DB::table('items')->where('name', 'knife')->doesntExist()); | ||
$this->assertTrue(DB::table('items')->where('name', 'ladle')->doesntExist()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like basic tests for exists()
and doesntExist()
methods. How is this related to the PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realized that was not tested when working on the aggregate method. That could be part of PHPORM-285 that I had to postpone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd agree that this is better off in a separate PR/commit. Or include it here but reference PHPORM-285 in the commit message (which can still be squashed at merge time, but at least we have a note pointing to the relevant issue).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed this tests and created #3257
I realized, only doesntExist was not tested.
['id' => 2, 'twos_min' => 4], | ||
], $results->get()); | ||
|
||
$results = EloquentWithAggregateModel1::withAvg(['twos' => $filter], 'value')->where('id', 2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In QueryBuilderTest, I noted there were two names for the same method: avg()
and average()
. Is there also a withAverage()
method that should be tested?
$modelIds = collect($models)->pluck($this->model->getKeyName())->all(); | ||
|
||
foreach ($this->withAggregate as $withAggregate) { | ||
if ($withAggregate['relation'] instanceof HasMany) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that this only applies some processing for HasMany relations, under what circumstances would different relations get appended to $this->withAggregate
? And are they OK being left as-is?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding an exception in the "else" case. I thing the only other case if "HasOne", but I need to check "BelongsToMany".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I addressed most comments but need to add tests on the new error cases.
@@ -650,6 +650,14 @@ public function aggregateByGroup(string $function, array $columns = ['*']) | |||
return $this->aggregate($function, $columns); | |||
} | |||
|
|||
public function count($columns = '*') | |||
{ | |||
// Can be removed when available in Laravel: https://github.com/laravel/framework/pull/53209 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then reverted again: laravel/framework#54196
|
||
public function testWithAggregate() | ||
{ | ||
EloquentWithAggregateModel1::create(['id' => 1]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This ensures that the initial query filter on id
works (perhaps I'm being too creative about what might fail).
tests/QueryBuilderTest.php
Outdated
$this->assertFalse(DB::table('items')->where('name', 'ladle')->exists()); | ||
$this->assertFalse(DB::table('items')->doesntExist()); | ||
$this->assertFalse(DB::table('items')->where('name', 'knife')->doesntExist()); | ||
$this->assertTrue(DB::table('items')->where('name', 'ladle')->doesntExist()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realized that was not tested when working on the aggregate method. That could be part of PHPORM-285 that I had to postpone.
|
||
$relations = is_array($relations) ? $relations : [$relations]; | ||
|
||
foreach ($this->parseWithRelations($relations) as $name => $constraints) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's adding the constraint closure from the scope and the relationships.
Fix PHPORM-238
Implement this feature from Laravel: https://laravel.com/docs/11.x/eloquent-relationships#counting-related-models
Counting relations with SQL is done using a subquery. For MongoDB, there is 2 ways:
$group
by foreign key.$lookup
to load references and count them. The process would be similar for embedded relations (without the$lookup
). But this doesn't work with hybrid relations.Checklist