laravel-mongodb - Issue #3541: has() / whereHas() fails when custom relationship keys are numeric strings

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Unknown
    • None
    • Affects Version/s: None
    • None
    • None
    • None
    • None
    • None
    • None

      misterneo has created Issue #3541: has() / whereHas() fails when custom relationship keys are numeric strings in laravel-mongodb. This Jira ticket was filed by GromNaN

      Issue Text:

      1. `has()` / `whereHas()` fails when custom relationship keys are numeric strings
        1. Environment
      • Laravel: 13.7.0
      • mongodb/laravel-mongodb: 5.7.1
      • mongodb/mongodb: 2.2.0
        1. Description

      `has()` and `whereHas()` appear to fail when a relationship uses custom string keys whose values are *numeric strings* (e.g. `"1"`, `"2"`).

      The relationship itself works correctly, but relationship existence queries (`has`, `whereHas`) return no results.

      Using non-numeric strings (e.g. `"item-1"`) works as expected.

        1. Reproduction

      Models

      ```php
      class ParentModel extends Model
      {
      public function children()

      { return $this->hasMany(ChildModel::class, 'parent_key', 'custom_key'); }

      }

      class ChildModel extends Model
      {
      public function parent()

      { return $this->belongsTo(ParentModel::class, 'parent_key', 'custom_key'); }

      }
      ```

      Documents

      *parents*

      ```json
      {
      "custom_key": "1"
      }
      ```

      *children*

      ```json
      {
      "parent_key": "1"
      }
      ```

      Working

      ```php
      ParentModel::first()->children;
      ParentModel::first()>children()>count();
      ChildModel::where('parent_key', '1')->exists();
      ```

      All of the above return the expected results.

      Failing

      ```php
      ParentModel::has('children')->get();
      ParentModel::whereHas('children')->get();
      ```

      These return an empty collection.

        1. Query log

      The generated query contains BSON integers instead of strings:

      ```json
      {
      "custom_key": {
      "$in": [

      { "$numberInt": "1" }

      ]
      }
      }
      ```

      However, the stored values are BSON strings:

      ```json
      {
      "custom_key": "1"
      }
      ```

      Since MongoDB performs strict type matching, the query returns no results.

        1. Additional observation

      If the values are changed from numeric strings to non-numeric strings, for example:

      ```json
      {
      "custom_key": "item-1"
      }
      ```

      and

      ```json
      {
      "parent_key": "item-1"
      }
      ```

      then `has()` and `whereHas()` work correctly.

      This suggests that somewhere during the relationship existence query, numeric strings are being coerced into integers before the `$in` query is constructed.

              Assignee:
              Unassigned
              Reporter:
              TPM Jira Automations Bot
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Created:
                Updated: