[BUG] hasMany and hasOne relation not working with ObjectId
florianJacques opened this issue · comments
Jacques Florian commented
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
Jacques Florian commented
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.
Jason commented
I have a simple replication for this issue