Skip to content

PHPLARA-250 Keep numeric string relation keys as strings in has queries - #3568

Open
Hashim1999164 wants to merge 4 commits into
mongodb:5.xfrom
Hashim1999164:fix/has-numeric-string-relation-keys
Open

PHPLARA-250 Keep numeric string relation keys as strings in has queries#3568
Hashim1999164 wants to merge 4 commits into
mongodb:5.xfrom
Hashim1999164:fix/has-numeric-string-relation-keys

Conversation

@Hashim1999164

@Hashim1999164 Hashim1999164 commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

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

  • Add tests and ensure they pass

@Hashim1999164

Copy link
Copy Markdown
Contributor Author

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.

@GromNaN GromNaN changed the title Keep numeric string relation keys as strings in has queries PHPLARA-250 Keep numeric string relation keys as strings in has queries Aug 24, 2026

@paulinevos paulinevos left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread src/Helpers/QueriesRelationships.php Outdated
{
$ids = is_array($relations) ? $relations : $relations->flatten()->toArray();

$originalIds = [];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you rename this $idsByStringKey for accuracy?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
@Hashim1999164

Copy link
Copy Markdown
Contributor Author

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.

@Hashim1999164

Copy link
Copy Markdown
Contributor Author

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

has() / whereHas() fails when custom relationship keys are numeric strings

2 participants