Replies: 7 comments
-
|
Please define custom keys? What do you mean by that? |
Beta Was this translation helpful? Give feedback.
-
|
Hey there, thanks for reporting this issue. We'll need more info and/or code to debug this further. Can you please create a repository with the command below, commit the code that reproduces the issue as one separate commit on the main/master branch and share the repository here? Please make sure that you have the latest version of the Laravel installer in order to run this command. Please also make sure you have both Git & the GitHub CLI tool properly set up. Do not amend and create a separate commit with your custom changes. After you've posted the repository, we'll try to reproduce the issue. Thanks! |
Beta Was this translation helpful? Give feedback.
-
|
I've created a repository here: https://github.com/Jade-GG/laravel-bug-report-after-query Here I've added a simple test relation using HasMany: public function tests(): HasMany
{
return $this
->hasMany(Test::class)
->afterQuery(fn($data) => $data->keyBy('test_number'));
}To reproduce the bug: Enter the tinker console: Check that the afterQuery works correctly when retrieving the relation I've created directly: User::first()->testsThis will return a collection keyed by User::with('tests')->first()->tests |
Beta Was this translation helpful? Give feedback.
-
|
@Jade-GG what is the use case for this? In your proposed fix, what happens if there are colliding keys? For example, in your seeder, instead of generating 10 test records with for ($i = 0; $i < 1000; $i++) {
Test::create([
'user_id' => $user->id,
'test_number' => rand(1, 10),
]);
}The I don't think this would make a good default. |
Beta Was this translation helpful? Give feedback.
-
What do you mean? My proposed fix is making eager loading here work the same as lazy loading.
Of course not, because that is not what I'm suggesting at all. It's just a piece of example code that I created solely to show the bug I'm reporting. My example here only exists to show the inconsistency between eager loading and lazy loading relationships when you try to use My proposed (partial) fix would only fix that part, retaining the keys that came directly from the query. If you then choose to not add the I'm not sure where the confusion is here. |
Beta Was this translation helpful? Give feedback.
-
|
@Jade-GG the confusion is generated by the fact that your keys may not always be the primary key or a unique key. |
Beta Was this translation helpful? Give feedback.
-
|
I'm moving this to Ideas for now. Belongs to many relationships primary key is optional in Laravel (only used when you have duplicate attached relationships, such as 1 users belongs to many teams with multiple roles). |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Laravel Version
12.36.1
PHP Version
8.3.24
Database Driver & Version
No response
Description
When you're using
afterQueryon an Eloquent relationship, with something like:The custom keys will be thrown away and replaced with standard incrementing keys (i.e. it turns back into a standard array). After a lot of searching I found out that this is seemingly caused by the
buildDictionaryfunction used in every relationship, which ignores custom keys completely and re-keys every array it comes across.For most relationships a fix for this would be fairly straightforward, for example BelongsToMany could be changed like this:
For
HasOneOrManyit's a bit more involved, but still possible.However, I do not know whether there would be any relevant knock-on effects from changing this behavior, which makes me uncertain whether it's a good idea to go through and fix all of them and create a pull request with that. Plus, there might be a better solution here that I don't know about.
Steps To Reproduce
hasManyrelationship)->afterQuery(...)on this relationship with a->keyBy(...)Beta Was this translation helpful? Give feedback.
All reactions