PHPLARA-250 Keep numeric string relation keys as strings in has queries - #3568
PHPLARA-250 Keep numeric string relation keys as strings in has queries#3568Hashim1999164 wants to merge 4 commits into
Conversation
|
Hybrid whereHas was matching string ids against integer author_id. Counting still uses string keys so numeric string custom keys work, then the original scalar type is restored for Mongo $in. |
paulinevos
left a comment
There was a problem hiding this comment.
Thanks for contributing! I added some test cases to ensure no regressions, there's still an edge case that fails for integer IDs.
Full disclosure: apart from that we're still on the fence if this would constitute a breaking change
| { | ||
| $ids = is_array($relations) ? $relations : $relations->flatten()->toArray(); | ||
|
|
||
| $originalIds = []; |
There was a problem hiding this comment.
Could you rename this $idsByStringKey for accuracy?
There was a problem hiding this comment.
Renamed, and switched the key itself. A string only map still merged int 1 with string "1", which is the integer edge case in the tests you added. idsByTypedKey keeps those two separate and still restores the original scalar for Mongo $in.
Integer 1 and string "1" were merged by array_count_values, which broke Pauline's mixed key tests. Keep a typed count key and restore the original scalar for $in.
|
Counted by type plus value so int 1 and string "1" stay distinct. Pauline's mixed key tests should pass now. The map is idsByTypedKey because a string only key still collided those two. |
|
@paulinevos The typed key map is in place so integer 1 and string "1" stay distinct for Mongo $in. The PHP 8.2 static analysis job is red on DocumentModel.php, including on 5.x, not on QueriesRelationships.php. Happy to re-review whenever you have time. |
Fixes #3541
has() and whereHas() collect related ids with array_count_values then array_keys. PHP promotes numeric string keys to integers, so the MongoDB $in query used integers against stored BSON strings and returned no documents.
This change stringifies the returned keys so values like "1" stay strings.
Checklist