Reputation: 3159
What is the difference between using belongsToMany() or hasManyThrough() when defining a Many To Many relationship in Laravel?
Example:
User
Account
Account_User
So, User has a many to many relation to Account via the Account_User table. On top of being just the pivot table that defines the related Users with related Accounts, it also stores a Account_User.role
field, which determines which role a given user has in a given account.
What would the implications be of using either User belongsToMany() Account
or User hasManyThrough() Account Account_User
? Or is this essentially the same?
When decided upon a method, I guess I should use the same method for the reverse relation definition.
Upvotes: 27
Views: 11021
Reputation: 53
I have struggled with this as well and came up with this solution in my head. A pivot table will have TWO keys to both entities it is related and it will be a belongsToMany
. If the middle table only has connections to one entity then it is a hasManyThrough
.
If I take all the examples given above:
Films
, Categories
there will be a middle table FilmCategories
with TWO keys to both Categories and Films and therefor it will be a belongsToMany
.
Company
, Office
, Employees
in this case we have 3 tables probably office points to company and employee points to office. None of the 3 tables will have keys to the other 2 so its a hasManyThrough
.
In the op's case there are 3 tables User
, Account
and Account_User
. This is a belongsToMany
because Account_User
will have keys to both Account
and User
.
Hope that helps a bit of a repeat and old question but it did confuse me a lot as well.
Upvotes: 0
Reputation: 4311
While @Arda's answer is absolutely correct, I found myself needing some time to digest it. So here is my attempt to put the same thing in simpler terms.
hasManyThrough
is useful when you have something similar to the following scenario:
Company
one-to-many Office
, and Office
one-to-many Employee
. And if you want to fetch all employees working for a given company, you need:// Company Model
public function employees()
{
return $this->hasManyThrough('App\Employee', 'App\Office');
}
belongsToMany
, on the other hand, is useful when you have a many-to-many relationship with a pivot table in-between. For example:
Film
many-to-many Category
. And if you want to fetch all categories for a given film, you need:// Film Model
public function categories()
{
return $this->belongsToMany('App\Category', 'pivot_table_name');
}
Given the scenario in question, belongsToMany
is the relationship needed to connect many Users
to many Accounts
. hasManyThrough
cannot be applied.
Upvotes: 13
Reputation: 6926
Let's say you have two models, let's call A
and B
:
If A
may have more than one items of B
,
and also
If B
may have more than one items of A
(think like blog posts / tags)
You have to use belongsToMany()
;
Now let's say you have 3 models, A
, B
and C
.
A
is related to B
, and B
is related to C
. But you need to access all C
's which is related to A
(over B
), then you need to use hasManyThrough()
(think like countries
-> users
-> posts
, and you need all post
s from specific country
)
hasManyThrough()
is not totally meant for many to many relationships, it's more like a shortcut.
Check the documentation links, 1, 2 (Laravel 4.2), or 3, 4 (Laravel 5.x).
Upvotes: 37