Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Many To Many relationships in Laravel: belongsToMany() vs. hasManyThrough()

Tags:

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.

like image 230
preyz Avatar asked Feb 11 '14 10:02

preyz


People also ask

How to define relationship in laravel?

To define a relationship, we need first to define the post() method in User model. In the post() method, we need to implement the hasOne() method that returns the result. Let's understand the one to one relationship through an example. First, we add the new column (user_id) in an existing table named as posts.

Has one through relationship laravel example?

Laravel hasOneThrough Relationship The “has-one-through” relationship links models through a single intermediate relation. For example, if each supplier has one product, and each product is associated with only one order, then the supplier model may access the product's order through the product.


2 Answers

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 posts 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).

like image 154
Arda Avatar answered Oct 08 '22 14:10

Arda


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-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:

  • A film can have many categories (comedy, drama, etc.) and each category can belong to many films. In other words, 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.

like image 25
Maksim Ivanov Avatar answered Oct 08 '22 13:10

Maksim Ivanov