Relationships in Laravel

Relationship in Laravel are the most beautiful and most scariest part at the same time. Beautiful because you don’t have to write long long queries to seek data between related entities as in traditional PHP. Scariest because it can lead to (n+1) optimisation problem which can really slow down your website by a huge factor.

First of all, thank you for your great response on my previous blog on Optimising Laravel Mails. If you haven’t read it yet, I would recommend to have a look here:

If relationships(in Laravel) are created and worked properly, you will definitely start to love Laravel and stick to it.

It is one of the part which takes some experience to know them and use them properly. I also got struck at them in my beginning and started hating Laravel but now when i know about them, I would not say that I know the whole deep concept, but yes, I have some basic knowledge about them and can query the database using Eloquent Relationship that saves a lot of time. Let’s start……

Relationship in Laravel are same as in real life easy to create but difficult to work on.

What is relationship ?

Relationship is nothing but just a function or you can call it a method that help connecting models(db table) together that are related to each other.

e.g. A user table can be related to a profile table or you can say user table and profile table have relationship between them. To be precise - User has a Profile or Profile belongs to a User. They have one to one relation with each other.

Types

Some common and most used types of relationships are :

  1. One To One
  2. One To Many
  3. Many To many

There are more but let’s discuss about these three in this blog.

One To One Relationship

As the name suggests, it’s the relationship of one model to the other model.

e.g A User model has one Profile.

One to one relationship

Syntax:

class User{
public function profile(){
return $this->hasOne(Profile::class);
OR
return $this->hasone('App\Models\Profile');
}
}

This code will build a relationship of user with profile model. Now you can access the profile of a user like this:

$profile = User::find(1)->profile;

The beauty of Eloquent is that it determines the foreign id on the table itself and if you have some other column, then you can provide it as a second argument to the hasOne function like this :

return $this->hasOne(Profile::class, 'foreign_key');

This function will search for profile on the basis of user’s table primary key i.e id. If you want to connect it with some other column, then you can also specify it like this:

return $this->hasOne(Profile::class,'foreign_key','local_key'); 

So this will look something like this,

return $this->hasOne(Profile::class,'profile_id','id');

Inverse of One to One

Now one thing will come into your mind is that how to fetch the user if you have profile with you. So for that purpose you have to specify the reverse of relationship like this:

class Profile{
public function user(){
return $this->belongsTo(User::class);
}
}

This function will let you access the user from profile like this :

Profile::find(1)->user;

All the other rules of foreign and local key apply to this also.

return $this->belongsTo(User::class, 'foreign_key', 'local_key'); 

That’s it… You have successfully created a one to one relationship between user and profile table/model.

One To Many Relationship

As the name suggests, one model is connected to more than one models i.e parent having multiple children or in more simple terms, one row of parent table having relationship with more than one or one row of child table. It seems to be little bit confusing but trust me it’s very simple. Let me give an example.

e.g A User can have multiple Orders.

One to Many relationship

Syntax :

class User{
public function orders(){
return $this->hasMany(Order::class);
OR
return $this->hasMany('App\Models\Order');
}
}

This will create a relationship between User and Order model where a user can have a single or multiple orders. You can fetch the orders of a user like this :

$orders = User::find(1)->orders;foreach($orders as $order){    //
}

Like the hasOne() method, you may also override the foreign and local keys by passing additional arguments to the hasMany() method like this :

return $this->hasMany(Order::class,'foreign_key','local_key');

Inverse of One to Many

If you want to get the user detail from the order, you can do something like this :

class Order{
public function user(){
return $this->belongsTo(User::class);
}
}

You can access user from order like so :

$user = Order::find(1)->user;

All the other rules of foreign and local key apply to this also.

return $this->belongsTo(User::class,'foreign_key','local_key');

Many To Many Relationship

As the name suggests, more than one model is connected to more than one models. It seems to be little bit more confusing than the hasOne and hasMany relations but trust me it’s also simple. Let me give an example.

e.g A User can have multiple Roles and a Role can belong to many Users.

Suppose there is a user who is having admin as well as user role and there can be multiple admins and users. In this case you have to use many to many relationship.

Many to Many relationship

In these types of relationship you have to create an extra table that is known as “pivot table”. In this case the table will be names as role_user. Remember Laravel users some naming convention so the pivot table should be separated by an underscore and should be arranged alphabetically.

The schema/structure of the pivot table will be this :

role_user ---> id
user_id
role_id

Syntax :

class User{
public function roles(){
return $this->belongsToMany(Role::class);
}
}

To access user Roles from user, you can do something like this :

$roles = User::find(1)->roles;foreach ($user->roles as $role) {
//
}

If you want to override the pivot table’s name, you can pass table name as a second argument like this :

return $this->belongsToMany(Role::class,'pivot_table_name');

To customise the column name you can use the third argument as the table column from which you are creating relationship like “user_id” and fourth argument as the table column to which you are pointing like “role_id” in the pivot’s table .The syntax will look something like this :

belongsToMany(Role::class,'pivot_table','reference_from_column','reference_to_column');

Inverse of Many to Many

Now if you want to get the list of users from roles model, do the same as done on users models like this :

class Role{
public function users(){
return $this->belongsToMany(User::class);
}
}

You can access users in your code like this :

$users = Role::find(1)->users;foreach ($roles->users as $user) {
//
}

All the rules are same as above for table naming and column naming .

That’s it.…. If you know about these three relationship, you can easily get advantage and use it in your code to make your queries a lot shorter.

Play around the code and go through it several times and if you still found any issue, shoot it in the comments and If you like the blog, then please hit that clap button and follow me for more such blog. I will be posting my next blog on it’s practical implementation. So stay tuned…

You can learn more about relationships here :

--

--

WEB LEARNER | WEB3 Enthusiast

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store