Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Eloquent hasOne vs belongsTo degenerate to same function if both keys are specified?

For the case of a one-to-one relationship, if I fully specify the keys in the method calls, is there a difference between hasOne and belongsTo relationships? Or, asked differently, if I used hasOne on both sides of the relation, would it be the same result?

like image 776
Kevin Buchs Avatar asked Oct 01 '14 21:10

Kevin Buchs


People also ask

What is the difference between belongsTo and hasOne?

The only difference between hasOne and belongsTo is where the foreign key column is located. Let's say you have two entities: User and an Account. In short hasOne and belongsTo are inverses of one another - if one record belongTo the other, the other hasOne of the first.

What is the difference between hasMany and BelongsToMany?

One to many(hasMany): A user has many(can have many) article. So, Many article belongs to one user; Many to many(BelongsToMany): A User can belongs to many forum. So, A forum belongs to many user.

What is hasOne in laravel?

hasOne relationship in laravel is used to create the relation between two tables. hasOne means create the relation one to one. For example if a article has comments and we wanted to get one comment with the article details then we can use hasOne relationship or a user can have a profile table.


1 Answers

Yes it works for some cases to specify the keys and make the relation work. And with some cases I mean mainly retrieving results. Here's an example:

DB

users                profiles
-----                --------
id                   id
etc...               user_id
                     etc...

Models

Using "wrong" relations with hasOne twice

class User extends Eloquent {
    public function profile(){
        return $this->hasOne('Profile');
    }
}

class Profile extends Eloquent {
    public function user(){
        return $this->hasOne('User', 'id', 'user_id');
    }
}

Queries

Let's say we wanted to get the user from a certain profile

$profile = Profile::find(1);
$user = $profile->user;

This is working. But it's not working how it's supposed to be. It will treat the primary key of users like a foreign key that references user_id in profiles.

And while this may work you will get in trouble when using more complicated relationship methods.

For example associate:

$user = User::find(1);
$profile = Profile::find(2);
$profile->user()->associate($user);
$profile->save();

The call will throw an exception because HasOne doesn't have the method associate. (BelongsTo has it)

Conclusion

Whereas belongsTo and hasOne may behave similar in some situations. They are clearly not. More complex interactions with the relationship won't work and it's nonsense from a semantic point of view.

like image 197
lukasgeiter Avatar answered Oct 12 '22 11:10

lukasgeiter