There has been many similar questions but I found the accepted answers unsatisfactory. There is no clear answer as far as I could find in existing questions.
For belongsTo() vs hasOne(), the common answer seem to be 'user' and 'phone' relationship. A user has one phone number and a phone number belongs to user. This is explained in detail at Laravel documentation also: https://laravel.com/docs/5.2/eloquent-relationships
Explanation is that the 'Phone' model holds the foreign key 'user_id'. So a phone number can not exist without a 'User' model but a user can exist without a phone. If a User model is deleted, then related Phone model should be removed. Which is all fine so far...
However it gets complicated when you have many to many relationships which use pivot tables. (the foreign key argument does not apply anymore since it lives in the pivot table).
Lets say we have model Company and User. The Company can have many Users and Users can have many Companies. Then we have a pivot table with name company_user and it holds company_id and user_id rows.
Lets say a user can belong to many different companies and companies can belong to many users where these sets are intersecting.
Lets say we have:
Companies:
Company1
Company2
Company3
Users:
User1
User2
User3
Pivot:
User1, Company1
User1, Company2
User2, Company1
User2, Company2
Here both User1 and User2 are members of Company1 and Company2 vice versa. But Company3 and User3 has no relations...(yet a Company can exist without a User vice versa).
So in essence, it would be correct to say User belongsToMany Companies and also Company belongsToMany Users, while also we could say User hasMany Companies and Company hasMany Users.
Now if we think of an analogy, one may come up with an explanation, Companies has Users but Users work there so they belongTo companies. But, what if the User in question is the owner of the company, therefore User has a company while Company belongsTo User.
Since both User and Company can live without each other. Can we say we must use hasMany relationship? (because earlier hasOne meant that User can exist without a Phone but Phone cannot exist without a User since belongsTo required a User to exist?)
What is the correct way to map the company-user relations in this example? and why? or does which one used makes any difference?
Thanks!
You are getting caught up in semantic weeds. Taking Laravel out of the equation for a second, your raw database structure is correct. You have a many to many relationship through an intermediary join table. The existence of the join table implies that there is some form of relationship that can exist between users and companies, but it doesn't imply anything about what that means or that it needs to exist. For your example of a user being employed vs owning a company, you should add an attribute on the join table such as 'role' which could be 'owner', 'employee', 'board-member', etc. Then when you access the relationship between a specific company and a user, you know what the relationship means.
Adding Laravel back into the equation, I believe the suggested way to incorporate via Eloquent is to use the belongsToMany approach. But remember that this is just a shortcut that the ORM uses to define this many to many relationship. When you consume the actual query builder functionality:
$user->companies
$company->users
It is fairly clear that you want the associated models on the other side of the join.
EDIT:
To answer the title question use belongsToMany for many to many relationships. Use hasMany if you have a one sided relationship in conjunction with belongsTo.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With