Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] hasMany and hasOne relation not working with ObjectId #2788

Open
florianJacques opened this issue Mar 21, 2024 · 2 comments
Open

[BUG] hasMany and hasOne relation not working with ObjectId #2788

florianJacques opened this issue Mar 21, 2024 · 2 comments

Comments

@florianJacques
Copy link
Contributor

Hello
The _id autocast is a problem on HasOne and HasMany relations, as it prevents comparisons with ObjectId

public function getIdAttribute($value = null)
{
    // If we don't have a value for 'id', we will use the MongoDB '_id' value.
    // This allows us to work with models in a more sql-like way.
    if (! $value && array_key_exists('_id', $this->attributes)) {
        $value = $this->attributes['_id'];
    }

    // Convert ObjectID to string.
    if ($value instanceof ObjectID) {
        return (string) $value;
    }

    if ($value instanceof Binary) {
        return (string) $value->getData();
    }

    return $value;
}

Indeed, this relationship always returns me null

public function accessToken(): HasOne
{
    return $this->hasOne(AccessToken::class, 'userId', '_id');
}

But if I remove the line

// Convert ObjectID to string.
if ($value instanceof ObjectID) {
    return (string) $value;
}

The relation working

@florianJacques
Copy link
Contributor Author

florianJacques commented Mar 21, 2024

I propose this solution to get around the problem without breaking the existing system.
What do you think?

protected bool $castKey = true;

public function getIdAttribute($value = null): mixed
{
    return $this->castKey ? parent::getIdAttribute($value) : $value;
}

public function accessTokens(): HasMany
  {
      $this->castKey = false;
      $hasMany =  $this->hasMany(AccessToken::class, 'userId', '_id');
      $this->castKey = true;

      return $hasMany;
  }

Unfortunately does not work with method....

I don't know why you put a default attribute mutator on the id, I wonder if it shouldn't be removed.

@masterbater
Copy link
Contributor

#2753 (comment)

I have a simple replication for this issue

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

No branches or pull requests

2 participants