Many To Many relationships in Laravel: belongsToMany() vs. hasManyThrough()
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:
- A company has many offices and each office has many employees working in it. In other words,
Company
one-to-manyOffice
, andOffice
one-to-manyEmployee
. 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:
- A film can have many categories (comedy, drama, etc.) and each category can belong to many films. In other words,
Film
many-to-manyCategory
. 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.
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).