You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi,
When using HasManyThrough::getQuery (or toRawSql, or any other using to getQuery under the hood), the query used is wrong, because prepareQueryBuilder wasn't called.
The result in the case I have encounter is wrong models attributes fetch, especially with wrong ids (id attribute is coming from the table joined).
One solution could be to override getQuery in HasManyThrough class to call prepareQueryBuilder or shouldSelect (which contains the wanted logic).
select * from "deployments" inner join "environments" on "environments"."id" = "deployments"."environment_id" where "environment"."application_id" = XX
instead of
select "deployments".*, "environments"."application_id" as "laravel_through_key" from "deployments" inner join "environments" on "environments"."id" = "deployments"."environment_id" where "environment"."application_id" = XX
The text was updated successfully, but these errors were encountered:
mathieutu
changed the title
HasManyThrough toBase error
HasManyThrough getQuery/toBase error
May 14, 2025
mathieutu
changed the title
HasManyThrough getQuery/toBase error
HasManyThrough getQuery error
May 14, 2025
/** * Get the underlying query for the relation. * * @return \Illuminate\Database\Eloquent\Builder */publicfunctiongetQuery()
{
return$this->query;
}
getQuery only retrieves the eloquent builder and could be called multiple times in a request. We would not recommend adding logic to it.
We noticed that toSql does not retrieve the right sql for relations and we had to throw exception in statement prepared event to get the actual sql that is being executed in order for us to async eager load relations using curl_multi_init (guzzle pool).
We did not bother to open an issue about it because relations are an extension of the eloquent builder so, this might be a known consequence.
The "logic" that would be added is only a addSelect. I don't see the issue with that.
(On my case, I'm passing the query to a function that expect an Eloquent\Builder object, hence the getQuery.)
That will break some use cases like select distinct from relation and others for sure. You can create a macro to solve your case or manually add extra things to the returned Eloquent Builder (clone to be sure you are not persisting the changes in the object).
Laravel Version
12.14.1
PHP Version
8.4
Database Driver & Version
Sqlite
Description
Hi,
When using
HasManyThrough::getQuery
(ortoRawSql
, or any other using togetQuery
under the hood), the query used is wrong, becauseprepareQueryBuilder
wasn't called.The result in the case I have encounter is wrong models attributes fetch, especially with wrong ids (
id
attribute is coming from the table joined).One solution could be to override
getQuery
inHasManyThrough
class to callprepareQueryBuilder
orshouldSelect
(which contains the wanted logic).framework/src/Illuminate/Database/Eloquent/Relations/HasOneOrManyThrough.php
Lines 520 to 526 in df12a08
I can make the PR if you want.
WDYT?
Thanks,
Mathieu
Steps To Reproduce
With the example from the doc:
$this->deployments()->toRawSql()
will returnselect * from "deployments" inner join "environments" on "environments"."id" = "deployments"."environment_id" where "environment"."application_id" = XX
instead of
select "deployments".*, "environments"."application_id" as "laravel_through_key" from "deployments" inner join "environments" on "environments"."id" = "deployments"."environment_id" where "environment"."application_id" = XX
The text was updated successfully, but these errors were encountered: