Skip to content

Relational Ids stored as Strings #356

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

Closed
rmedcalf opened this issue Nov 9, 2014 · 16 comments
Closed

Relational Ids stored as Strings #356

rmedcalf opened this issue Nov 9, 2014 · 16 comments
Labels

Comments

@rmedcalf
Copy link

rmedcalf commented Nov 9, 2014

Wouldn't it be correct to store them as ObjectId?

I have a user object

public function role()
{
    return $this->belongsTo('Bbfx\Models\Role');
}

My role object

public function user()
{
    return $this->hasOne('Bbfx\Models\User');
}

When saved, a user document is created and has the correct role_id but the role_id type is String. The mongodb documentation says this should be an ObjectId

@rmedcalf rmedcalf changed the title Why are relation ids strings? Relational Ids stored as Strings Nov 9, 2014
@rmedcalf
Copy link
Author

rmedcalf commented Nov 9, 2014

I think this is also the same problem the guy in issue #350 is seeing

@rmedcalf
Copy link
Author

rmedcalf commented Nov 9, 2014

Possible workaround is to use the attribute mutator

public function setRoleIdAttribute($value)
{
    $this->attributes['role_id'] = new \MongoId($value);
}

or override the save method in hasone.php

public function save(\Illuminate\Database\Eloquent\Model $model)
{
    $value = new \MongoId($this->getParentKey());
    $model->setAttribute($this->getPlainForeignKey(), $value);

    return $model->save() ? $model : false;
}

or perhaps just override getParentKey

public function getParentKey()
{
    $value = $this->parent->getAttribute($this->localKey);
    return new \MongoId($value);
}

Anyone see any issues by doing that?

@jmshelby
Copy link

jmshelby commented Nov 9, 2014

I asked about this in #134 ... But I would still like to see this implemented some time, maybe as an option. One day when I have enough time, I'll try and see exactly what issues jens ran into, and find solutions ....

@rmedcalf
Copy link
Author

rmedcalf commented Nov 9, 2014

My code above appears to take care of the insert but now I'm having issues with retrieving the objects with those modifications. So yeah, he pretty much sums it up in his comment.

@rmedcalf
Copy link
Author

rmedcalf commented Nov 9, 2014

OK. With my changes I can do this and get the expected result:

    $user = User::where('user_name', '=', 'rmedcalf')->with('role')->first();
    var_dump($user->role->type);

This is a one-to-one relationship with the role_id being saved as an ObjectId rather than string

Changes that had to be done

HasOne.php:

public function getParentKey()
{
    $value = $this->parent->getAttribute($this->localKey);
    return new \MongoId($value);
}

BelongsTo.php:

public function match(array $models, Collection $results, $relation)
{
    $foreign = $this->foreignKey;

    foreach($models as $m)
    {
        if(gettype($m->$foreign == 'object') && get_class($m->$foreign) == 'MongoId')
        {
            $m->$foreign = (string)$m->$foreign;
        }
    }

    return parent::match($models, $results, $relation);
}

I'm sure there are things I'm not considering.. Would like the author's feedback
Thanks!

@jenssegers
Copy link
Contributor

I agree that MongoId's are better, but it was too hard too implement it with the current way Eloquent is working. When Laravel 5 is released, and I can find some spare time, I will be looking into this.

@developerdino
Copy link

Is there any movement on this - I'm dealing with a legacy db which uses ObjectId throughout which I can't change.

@stratease
Copy link

Would love to see this implemented too. I'm probably going to implement a workaround like the one listed above - not excited about it.

@jenssegers
Copy link
Contributor

I have been trying to do this for quite a while, but it takes a lot more changes than the one above. I'll have another go at it this weekend.

@barroca
Copy link

barroca commented Jul 29, 2015

+1 on having this implemented. Thanks

1 similar comment
@omidahn
Copy link

omidahn commented Aug 29, 2015

+1 on having this implemented. Thanks

@martingg88
Copy link

+1

@rohitkhatri
Copy link

+1 on having this implemented. Thanks

@ericsala
Copy link

+1

1 similar comment
@Oleg-Arkhipov
Copy link

+1

@maslauskas
Copy link

+1 would really love to see this implemented

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests