-
Notifications
You must be signed in to change notification settings - Fork 11.7k
Description
Laravel Version
12.36.1
PHP Version
8.3.24
Database Driver & Version
No response
Description
When you're using afterQuery on an Eloquent relationship, with something like:
return $this->hasMany(Product::class)
->afterQuery(fn ($result) => $result->keyBy('product_id'));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 buildDictionary function 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:
- foreach ($results as $result) {
+ foreach ($results as $key => $result) {
$value = $this->getDictionaryKey($result->{$this->accessor}->{$this->foreignPivotKey});
- $dictionary[$value][] = $result;
+ $dictionary[$value][$key] = $result;
}For HasOneOrMany it'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
- Create two Eloquent models that relate to each other in some way (e.g. a
hasManyrelationship) - Relate them with an Eloquent relationship
- Try to use
->afterQuery(...)on this relationship with a->keyBy(...) - Dump what comes out of this relationship and observe that the custom keys you tried to add have been removed.