Complete Guide on Laravel Relationships

by Eric McWinNEr

.

Updated Sun Jun 18 2023

Complete Guide on Laravel Relationships

Complete Guide on “Laravel Eloquent Relationships” provides an in-depth and easy to understand guide on defining database relationships in Laravel using Laravel Eloquent.

Laravel developers make use of Laravel Eloquent daily and can run into different issues with defining and setting up their relationship structure for their project.

Since there are many types of database relationships and even polymorphic relationships in Laravel eloquent, how do you know which one to pick and when to choose which type of relationship?

And how to utilize the full potential of that type of relationship you have chosen when it comes to querying and manipulating the model.

By the way, if you’re just STARTING out with Laravel, I have created a Complete Laravel Guide just for you.

This article aimed at providing a complete guide on “Laravel relationships” and discuss different types of “Laravel relationships”, which one best suits your project, and how to query or manipulate the Laravel Models efficiently to increase performance.

Before we dive into the article, subscribe to get access to our free laravel tips that will improve your productivity.

Prerequisites 

  • Basic knowledge of Laravel
  • Basic usage of Laravel Eloquent

Introduction

Let’s imagine for a second that we’re building a voting system — we would need to store our users, candidates, political parties, and votes in our database.

When we store candidates, we would need to know which political party the candidate belongs to.

In the same way, when storing votes, we would need to know which user cast that vote, as well as the political party the user voted for (and by relationship the candidate[s] who received the votes). 

As you can see, the users, candidates, political parties, and votes are all different but related entities in our database.

If you’re familiar with working with relational databases like MySQL or PostgreSQL, you’ll understand that most times database tables are related to each other.

Laravel provides an Object Relational Mapper called Eloquent

Laravel Eloquent allows us to query our database without bothering if it’s MySQL or PostgreSQL or MongoDB.

just use the same set of methods and Eloquent handles the dirty work.

Getting Started with Laravel Relationships 

Eloquent also makes it easy to store and manipulate database relationships and database entities as if they are plain PHP objects.

This eliminates the need to interact with your database most of the time.

It provides different types of Laravel relationships namely;

  • Normal relationships 
  • Polymorphic Relationships 
  • Dynamic Relationships

Normal Relationships 

This is a normal relational database relationship between the data tables of the database.

It is basically the interconnection of different tables for data integrity and to avoid redundancy of data.

It provides 3 main types of relationships and 2 intermediate types.

  1. One To One
  2. One To Many
  3. Many To Many
  4. Has One Through
  5. Has Many Through

Let’s take a dive into each of these laravel relationships as we describe what they mean and how we can define them.

We will also split the article into sections, so you can jump right into the topic you find confusing.

One To One Relationships

A one-to-one relationship is a very basic, fundamental relationship.

It simply relates one entity to another.

For instance, in our voting application, a User is associated with one Vote.

If we were to describe this relationship, we could say:

Each user has one vote.

In order to define this relationship, we call the hasOne method on the entity that owns the relationship.

Here’s a code snippet defining the relationship, “Each user has one vote”

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Get's this user's vote
     */
    public function vote()
    {
        return $this->hasOne(App\Models\Vote::class);
    }
}

You can get an in-depth article on Laravel One to One relationship with an example that explains everything from creating the relationship, the inverse method of creating it, and how to retrieve the data here.

Take a break and subscribe to get access to our free laravel tips that will improve your productivity.

One To Many Relationships

One to many relationships is used to define situations where one entity in our database is related to many entities of the same type in our database.

Going back to our voting system example, we can see that the political parties and candidates have a one to many relationship. 

A political party can have many candidates — at least two candidates for each category of elections, for the running mates; and it could have several candidates if we make it extend to the presidential, governorship, and other levels of elections.

However, a candidate can only belong to one political party (at a time at least). 

If we were to define this relationship in plain English, we’d say:

“A political party has many candidates”.

Eloquent makes it easy to define such relationships. Go ahead and take a guess at how Laravel Eloquent defines it?

Well, it’s done by using the hasMany method (I hope you got it right 🙂 ).

We use it like this:

<?php
  namespace App\Models;

  use Illuminate\Database\Eloquent\Model;

  class PoliticalParty extends Model {
    
    /**
    * Get the candidates this party has
    */
    public function candidates() {
      return $this->hasMany(App\Model\Candidate::class); 
    }
    
  }

You can get an in-depth article on Laravel one to many relationships with examples that explain everything from creating the relationship, the inverse method of creating it, and how to retrieve the data.


Many To Many Relationships

Many to many relationships are a bit more involved than One to One and One to Many relationships.

Let’s first explain a possible use-case for this relationship :

 Imagine we’re building an e-commerce website that allows multiple vendors to sell a certain set of products through our platform.

In this system, it would be possible to have multiple vendors selling the same product. If we wanted to relate vendors to products, it would be a bit tricky.

We can’t use one to one or one to many relationships in this case, because each product is related to several vendors and each vendor is related to several products as well.

Laravel Eloquent lets us create relationships like this, but it requires some additional setup on our part. 

The first step is to set up our database structure. We’ll need three tables to define this relationship:

The two tables that have a relationship and a third table called pivot table. In our example, the tables would be: vendors, products and product_vendor.

The function of the third table is to store all relationships between products and vendors’ tables. It needs two required columns: product_id and vendor_id to complete the relationship.

In this case, both sides of the relationship would use the belongsToMany method to define the relationship.

Here’s an example:

class Product extends Eloquent {
<?php
  namespace App\Models;

  use Illuminate\Database\Eloquent\Model;

  class Product extends Model {
    
    /**
    * Get the party this user voted for.
    */
    public function vendors() {
      return $this->belongsToMany(App\Model\Vendor::class); 
    }
    
  }

You can get an in-depth article on Laravel many to many relationships with examples that explain everything from creating the relationship, interacting with the pivot table, defining the inverse of the relationship, retrieving the data, and use-case examples here.

Take a break and subscribe to get access to our free laravel tips that will improve your productivity.


Has One Through

A HasOneThrough relationship is used to define relationships between two entities that have no direct relationship with each other but are each related by a third entity. 

In order to give an example of a use case for this relationship, let’s look back at our voting system.

In an election, each user is only allowed to have one vote and each vote should have one party.

So we would be able to get the party each user voted for through their vote. Even if the party and users have no direct relationship, since they are both related to the vote, we can access them through that vote.

In order to define this relationship, we use the hasOneThrough method as described below:

<?php
  namespace App\Models;

  use Illuminate\Database\Eloquent\Model;

  class User extends Model {
    
    /**
    * Get the party this user voted for.
    */
    public function party() {
      return $this->hasOneThrough(App\Model\Party::class, App\Model\Vote::class); 
    }
    
  }

As seen, this is a bit different from the other methods above.

Here, the first argument is the final entity we wish to access (political party) and the second argument would be the related entity (vote).

You can get a more in-depth article, that describes in detail the table structure of each entity and how to retrieve the relationship.


Has Many Through Relationship

This is very similar to the “has-one-through” relationship described above.

Just like has one through relationships, they are used to define relationships between two entities that are each related to a third entity but this is used when we want to get multiple values.

As usual, here’s a use case — remember the e-commerce website we imagined? Come on, I know you do. In our example, a vendor would have many user reviews for his products.

A vendor and a user review may not have any relationship, but we would be able to easily get all his user reviews through his products by defining a hasManyThrough relationship.

Here’s how we define this relationship:

<?php
  namespace App\Models;

  use Illuminate\Database\Eloquent\Model;

  class Vendor extends Model {
    
    /**
    * Get this vendor's product reviews
    */
    public function reviews() {
      return $this->hasManyThrough(App\Model\Review::class, App\Model\Product::class); 
    }
    
  }

You can get a more in-depth article here, that describes in detail the table structure of each entity and how to retrieve the relationship.

Getting Started with Polymorphic Relationships

This is a type of relationship provided by Laravel Eloquent, where a target model is allowed to belong to more than one type of model using a single association.

This type of relationship also provides 3 main type of relationships.

  1. One To One (Polymorphic)
  2. One To Many (Polymorphic)
  3. Many To Many (Polymorphic)

Let’s take a dive into each of these relationships as we describe what they mean and how we can define them.

One to One(Polymorphic) Relationships

One to One Polymorphic relationships are very similar to normal One to One relationships, but they are used to define relationships where the owner of the relationship could be more than one type of entity.

In an e-commerce application, we could decide to create virtual wallets for both vendors and normal users in our application.

Each vendor and user would have to have one wallet.

Here, a wallet would be related to either a vendor or a user. So it’s a one to one relationship, but it could be with either a User or a Vendor, that’s why it’s termed Polymorphic.

We define this relationship using the morphTo and morphOne for the target and owners respectively.

Here’s how we’d do it:

<?php
  namespace App\Models;

  use Illuminate\Database\Eloquent\Model;

  class Wallet extends Model {
    
    /**
    * Defines the owner of the wallet
    */
    public function walletable() {
      return $this->morphTo(); 
    }
    
  }

  class User extends Model {
    /**
    * Defines the wallet this user owns
    */
    public function wallet() {
      return $this->morphOne(App\Models\Wallet::class, 'walletable'); 
    }
  }

  class Vendor extends Model {
    /**
    * Defines the wallet this vendor owns
    */
    public function wallet() {
      return $this->morphOne(App\Models\Wallet::class, 'walletable'); 
    }
  }

You can get an in-depth article on Laravel one to one polymorphic relationship with example that describes how to retrieve the relationship, define the inverse of this relationship, and more here.

Take a break and subscribe to get access to our free laravel tips that will improve your productivity.

One to Many(Polymorphic) Relationships

One to many polymorphic relationships is just like one to many relationships, with the exception that the owner of the relationship could be more than one type of entity.

Going back to our e-commerce website, it’s possible for both users and vendors to have multiple bank cards that transactions can be made to and fro.

So, the bank card has a one to many polymorphic relationships with both users and vendors.

We define this relationship like this:

<?php
  namespace App\Models;

  use Illuminate\Database\Eloquent\Model;

  class Card extends Model {
    
    /**
    * Defines the owner of the wallet
    */
    public function cardable() {
      return $this->morphTo(); 
    }
    
  }

  class User extends Model {
    /**
    * Defines the wallet this user owns
    */
    public function card() {
      return $this->morphMany(App\Models\Card::class, 'cardable'); 
    }
  }

  class Vendor extends Model {
    /**
    * Defines the wallet this vendor owns
    */
    public function card() {
      return $this->morphMany(App\Models\Card::class, 'cardable'); 
    }
  }

You can get an in-depth article on Laravel one to many polymorphic relationship with example that describes how to retrieve the relationship, define the inverse of this relationship, and more here.

Many to Many(Polymorphic) Relationships

Many to Many Polymorphic Relationships are more involved than One to Many and Many to Many normal relationships.

Let’s give a use-case for this:

Imagine if we were creating a forum in our e-commerce app for vendors and users of our app to communicate.

If our vendors could post either Questions or Posts to this forum, they could share a polymorphic many to many relationship with a Category model.

Because a Question or Post could belong to multiple categories and a Category would contain multiple questions and posts.

Just like in Many to Many relationships, we would need a pivot table to relate the three tables categories, questions and posts.

We would define this relationship like this:

<?php
  namespace App\Models;

  use Illuminate\Database\Eloquent\Model;

  class Category extends Model {
    
    /**
    * Defines all posts that belong to this category
    */
    public function posts() {
      return $this->morphedByMany(App\Models\Post::class, 'categorical'); 
    }
    
    /**
    * Defines all questions that belong to this category
    */
    public function questions() {
      return $this->morphedByMany(App\Models\Question::class, 'categorical'); 
    }    
    
  }

  class Question extends Model {
    
    /**
    * Defines all the categories for this question
    */
    public function categories() {
      return $this->morphToMany(App\Models\Category::class, 'categorical'); 
    }
  }

  class Post extends Model {
    
    /**
    * Defines all the categories for this post
    */
    public function categories() {
      return $this->morphToMany(App\Models\Category::class, 'categorical'); 
    }
  }

You can get an in-depth article Laravel many to many polymorphic relationship with example that describes how to retrieve the relationship, the table structure, define the inverse of this relationship, and more here.

Take a break and subscribe to get access to our free laravel tips that will improve your productivity.

Dynamic Relationship

Laravel Eloquent provides a relationship called Dynamic Relationship which is barely used in development except when building a Laravel package.

Using this method resolveRelationUsing, you can create a relationship between Eloquent models at runtime.

Conclusion 

Laravel relationships are very important in the development of scalable applications. It allows us to create real-world data-structures, relationships, and manipulate our data more efficiently and in a predictable way.

In Complete Guide on Laravel Relationships, we have learned how to use them and implement them efficiently which would make development so much easier.

Whenever you're ready

There are 3 ways we can help you become a great backend engineer:

The MB Platform

Join 1000+ backend engineers learning backend engineering. Build real-world backend projects, learn from expert-vetted courses and roadmaps, track your learnings and set schedules, and solve backend engineering tasks, exercises, and challenges.

The MB Academy

The “MB Academy” is a 6-month intensive Advanced Backend Engineering BootCamp to produce great backend engineers.

Join Backend Weekly

If you like post like this, you will absolutely enjoy our exclusive weekly newsletter, Sharing exclusive backend engineering resources to help you become a great Backend Engineer.

Backend Tips, Every week

Backend Tips, Every week