-
Notifications
You must be signed in to change notification settings - Fork 11.3k
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
withCount not working as expected #35059
Comments
@paras-malhotra The test changed to support new query including limit 1 only and not anything else. @nnerijuss I'm gonna create a project as your steps, but if you can share a gist from your source. |
I understand @khalilst, I'm not criticising the PR at all - great work on the PR! Just saying that the limit 1 change may be the issue here. |
@khalilst I really do not understand what more can i share with you to help you solve this issue. app/Product.php class Product extends Model
{
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
public function scopeWithCommentsCount(Builder $builder): Builder
{
return $builder->withCount([
'comments' => function ($query) {
$query->whereNotNull('confirmed_at');
}
]);
}
} app/Comment.php class Comment extends Model
{
} Call withCount scope: Products::withCommentsCount()->whereIn('id', [1,2,3,4])->get(); If you convert this eloquent query to Mysql query you will get something like this: SELECT
`id`,
(SELECT
COUNT(*)
FROM
`comments`
WHERE
`products`.`id` = `comments`.`commentable_id`
AND `comments`.`commentable_type` = 'App\\Product'
AND `comments`.`confirmed_at` IS NOT NULL
LIMIT 1) AS `comments_count`
FROM
`products`
WHERE
`id` IN (1 , 2, 3, 4) I write this code on the fly, but idea is similar to my production code(Sorry, repo is private and i cant share full codebase with you). As you can see, there is |
@nnerijuss I have created a project with your steps and everything works fine. Psy Shell v0.10.4 (PHP 7.4.11 — cli) by Justin Hileman
>>> Product::withCount(['comments'=> fn($q) => $q->whereNotNull('confirmed_at')])->get()
[!] Aliasing 'Product' to 'App\Models\Product' for this Tinker session.
=> Illuminate\Database\Eloquent\Collection {#3964
all: [
App\Models\Product {#3926
id: 1,
name: "fSbKRoIpBl",
created_at: "2020-11-02 09:48:39",
updated_at: "2020-11-02 09:48:39",
comments_count: 2,
},
App\Models\Product {#4173
id: 2,
name: "TBpEYufkJI",
created_at: "2020-11-02 09:48:39",
updated_at: "2020-11-02 09:48:39",
comments_count: 2,
},
App\Models\Product {#3965
id: 3,
name: "iBlkWmyfU3",
created_at: "2020-11-02 09:48:39",
updated_at: "2020-11-02 09:48:39",
comments_count: 0,
},
App\Models\Product {#3558
id: 4,
name: "c0o1InKesx",
created_at: "2020-11-02 09:48:47",
updated_at: "2020-11-02 09:48:47",
comments_count: 2,
},
],
} |
@khalilst what version of Mysql do you use ? Both of my enviroments(local and production) works on same mysql 8.0.18 version, and i have this problem in both environments. Until upgrading to Laravel 8 i do not faced this issue. |
@nnerijuss I think you have problem with your data. As I told you Server version: 8.0.20 MySQL Community Server - GPL And this is test result with your new code. Everything is fine again: >>> Product::withCommentsCount()->whereIn('id', [1,2,3,4])->get();
[!] Aliasing 'Product' to 'App\Models\Product' for this Tinker session.
=> Illuminate\Database\Eloquent\Collection {#4175
all: [
App\Models\Product {#3925
id: 1,
name: "fSbKRoIpBl",
created_at: "2020-11-02 09:48:39",
updated_at: "2020-11-02 09:48:39",
comments_count: 2,
},
App\Models\Product {#4173
id: 2,
name: "TBpEYufkJI",
created_at: "2020-11-02 09:48:39",
updated_at: "2020-11-02 09:48:39",
comments_count: 2,
},
App\Models\Product {#4174
id: 3,
name: "iBlkWmyfU3",
created_at: "2020-11-02 09:48:39",
updated_at: "2020-11-02 09:48:39",
comments_count: 0,
},
App\Models\Product {#3557
id: 4,
name: "c0o1InKesx",
created_at: "2020-11-02 09:48:47",
updated_at: "2020-11-02 09:48:47",
comments_count: 2,
},
],
} You can see the >>> Product::withCommentsCount()->whereIn('id', [1,2,3,4])->toSql()
=> "select `products`.*, (select count(*) from `comments` where `products`.`id` = `comments`.`commentable_id` and `comments`.`commentable_type` = ? and `confirmed_at` is not null limit 1) as `comments_count` from `products` where `id` in (?, ?, ?, ?)" |
@khalilst thanks, but still very strange. I have seeded absolutely fresh data, and still have facing same issue. Without I try to dig in little bit more, because i don't understand why same query works in your machine and do not works in mine(even when local and production machines ar absolutely different). |
@nnerijuss |
@khalilst there is full repo with my test models and data. You can see in Readme.md file the result i get in executed command. I hope this will help you. |
@khalilst @nnerijuss Cannot confirm. I get the correct counts: array:4 [
0 => array:5 [
"id" => 1
"comments_count" => 2
]
1 => array:5 [
"id" => 2
"comments_count" => 2
]
2 => array:5 [
"id" => 3
"comments_count" => 0
]
3 => array:5 [
"id" => 4
"comments_count" => 2
]
] I'm still curious why this |
@dbakan Because the Post::withAggregate('comments', 'confirmed_at'); //without third argument And it returns the first comment |
@nnerijuss I confirm the problem exists in your provided application. |
@khalilst Thank you for clarifying! |
This will be fixed in tomorrow's patch release. Thanks all. |
Description:
After upgrading Laravel from 7 to 8
$model->withCount('relation')
returns unexpected value because of the limit 1 inIlluminate/Database/Eloquent/Concerns/QueriesRelationships.php
file417
row.Steps To Reproduce:
products
) with ids(1,2,3,4) with morphMany relation, for examplecomments
comments
table with column(id
,comment
,confirmed_at
)confirmed_at
date now date, or some other dateconfirmed_at
columnnull
Products::withCount(['comments'=> fn($q) => $q->whereNotNull('confirmed_at')])
Expected result:
Result returned:
After removing
->limit(1)
inIlluminate/Database/Eloquent/Concerns/QueriesRelationships.php
file417
row, everything starts working as expected.The text was updated successfully, but these errors were encountered: