DEV Community

Cover image for Exploring Laravel Eloquent in Depth
Asekhame Joel
Asekhame Joel

Posted on

Exploring Laravel Eloquent in Depth

Introduction

At some point in every developer's career, interacting with a database becomes an essential task. This is where Eloquent, Laravel's powerful object-relational mapper (ORM), comes into play. In my previous article on Models, I briefly discussed Eloquent, but this article is entirely dedicated to exploring it in depth. Eloquent simplifies the process of working with database tables by providing an intuitive and natural way to interact with your data. It allows developers to manage database records as if they were working with regular PHP objects, making database operations more efficient and less error-prone.

For developers using Laravel, it is important to know the six most important relationship types in Eloquent. These relationships determine how various database tables relate and how data can be accessed and manipulated across them. Knowing these relationships not only makes you better at designing solid database schemas but also makes your application capable of managing complex data interactions with ease. In the sections to come, we'll discuss and examine these six important relationship types in depth, giving you the information you need to use Eloquent to your advantage in your applications.

What Are Relationships in Eloquent?

To begin, let’s talk about relationships in Eloquent. What exactly are relationships in Eloquent? Just as the name suggests, a relationship defines how different entities are connected.
For example, consider a mother and her daughter. A mother has a child, and that child is directly linked to her mother. This connection is a relationship—it defines how one entity (the mother) is associated with another (the daughter). Similarly, in a database, relationships define how different tables are linked and how they interact with each other. Just as a mother can have multiple children, a database table can have multiple related records in another table. Or, just as a child belongs to a specific mother, a record in one table may belong to a single record in another.

In Eloquent, relationships allow you to establish meaningful connections between models, which represent database tables. These relationships make it easy to retrieve related data without writing complex queries manually. Instead of dealing with raw SQL joins, Eloquent provides a simple and intuitive syntax to define and manage relationships. This powerful feature helps developers organize, manage, and interact with structured data efficiently while keeping the code clean and readable.
For example, in a blogging application, you might have a User model and a Post model. A user can have many posts, and each post belongs to a specific user. By defining relationships in Eloquent, you can easily retrieve all posts written by a user or find the author of a specific post without writing complex SQL queries. Nevertheless, in this article I would explain the most used relationships in eloquent and how they work.

1. One-to-One Relationship
A one-to-one relationship is the simplest type of relationship in database design, where a single record in one table is directly associated with exactly one record in another table. This type of relationship is often used to store additional or supplementary information in a separate table while maintaining a clear connection between related records.

For example, in a blogging application, a User might have one Profile, and each Profile belongs to a single User. The users table contains basic information such as id, name, and email, while the profiles table holds additional details like id, user_id, bio, and avatar. The user_id in the profiles table acts as a foreign key, linking each profile to a specific user by referencing the id in the users table. This setup ensures that each user has only one profile and that each profile belongs to a single user, making it easy to retrieve additional user details when needed.

Using the mother and daughter relationship i used earlier a one-to-one relationship is the relationship between a mother and her daughter. Each mother has only one biological daughter (in this scenario), and each daughter has only one biological mother. In a database, this relationship is represented by having one table reference another through a foreign key. For instance, a mothers table and a daughters table can be structured so that the daughters table includes a mother_id, which links each daughter to exactly one mother.

Code Explanation and Output
In Eloquent, you define a one-to-one relationship by using the hasOne method in the User model and the belongsTo method in the Profile model. This means that a user can have one profile, and each profile belongs to a single user. Essentially, the hasOne method establishes that a user can have only one profile, while the belongsTo method indicates that each profile is linked to one specific user. This setup ensures a direct and unique connection between a user and their profile.

// User Model
class User extends Model {
    public function profile() {
        return $this->hasOne(Profile::class);
    }
}

// Profile Model
class Profile extends Model {
    public function user() {
        return $this->belongsTo(User::class);
    }
}
Enter fullscreen mode Exit fullscreen mode

To retrieve a user's profile, you can use the following code:

$user = User::find(1);
$profile = $user->profile;
Enter fullscreen mode Exit fullscreen mode

Output
If the user with ID 1 has a profile, $profile will contain the profile details, such as bio and avatar. If no profile exists, $profile will be null.

2.One-to-Many Relationship
A one-to-many relationship is one of the most common types of relationships, where a single record in one table is associated with multiple records in another table. To make you understand this better, think about a mother and her children. A mother can have multiple children, but each child has only one biological mother. one mother, many children. One-to-Many Relationship is typically represented by having one table reference another using a foreign key. For example, let's say we have a mothers table and a children table. The children table will contain a column called mother_id, which links each child to a specific mother. For instance using a real application scenerio, in a blogging platform, a User can create many Post records, but each Post belongs to only one User. The users table might include columns like id, name, and email, while the posts table contains columns such as id, user_id, title, and content. The user_id in the posts table serves as a foreign key, linking each post to the user who created it. This allows you to efficiently retrieve all posts written by a specific user, ensuring a clear and manageable connection between users and their posts.

Code Explanation and Output
In Eloquent, you define a one-to-many relationship by using the hasMany method in the User model and the belongsTo method in the Post model. This means that a user can have many posts, and each post belongs to a single user. Essentially, the hasMany method establishes that a user can create multiple posts, while the belongsTo method indicates that each post is associated with one user. You Gerrit?

// User Model
class User extends Model {
    public function posts() {
        return $this->hasMany(Post::class);
    }
}

// Post Model
class Post extends Model {
    public function user() {
        return $this->belongsTo(User::class);
    }
}
Enter fullscreen mode Exit fullscreen mode

To retrieve all posts by a user, you can use the following code:

$user = User::find(1);
$posts = $user->posts;
Enter fullscreen mode Exit fullscreen mode

Output
If the user with ID 1 has created posts, $posts will be a collection of all posts associated with that user. If no posts exist, the collection will be empty.

3.Many-to-One Relationship
A many-to-one relationship is essentially the inverse of a one-to-many relationship, where multiple records in one table are associated with a single record in another table. This relationship is used when many entities belong to or are linked to a single entity. for example, still using our mother to children scenerio, Think about a mother and her children again, but this time from the child’s perspective. Each child has only one biological mother, but a mother can have multiple children. So, from the child’s point of view, this is a many-to-one relationship—many children belong to one mother. This is represented the same way as one-to-many, but now we focus on the "many" side (the children). Each child must have a mother, so the children table stores a mother_id to link each child to a specific mother.

In a real word application, For example, in a blogging platform, many Post records can belong to a single User. The users table might include columns like id, name, and email, while the posts table contains columns such as id, user_id, title, and content. The user_id in the posts table acts as a foreign key, linking each post to its author. This setup allows you to easily determine the author of a post by querying the users table using the user_id from the posts table, ensuring a clear and efficient relationship between posts and their authors.

Code Explanation and Output
The code for a many-to-one relationship is essentially the same as for a one-to-many relationship, but the perspective shifts. Instead of focusing on the "one" side (like a user having many posts), you focus on the "many" side (like posts belonging to a user). To define this relationship, you use the belongsTo method in the Post model. This means that each post belongs to a single user, establishing a clear link between the post and its author. So, while the one-to-many relationship is defined in the User model using hasMany, the many-to-one relationship is defined in the Post model using belongsTo.

// Post Model
class Post extends Model {
    public function user() {
        return $this->belongsTo(User::class);
    }
}
Enter fullscreen mode Exit fullscreen mode

To retrieve the author of a post, you can use the following code:

$post = Post::find(1);
$user = $post->user;
Enter fullscreen mode Exit fullscreen mode

Output
If the post with ID 1 has an associated user, $user will contain the user details, such as name and email. If no user is associated, $user will be null.

4.Many-to-Many Relationship
A many-to-many relationship occurs when multiple records in one table are associated with multiple records in another table. This type of relationship is used when entities from both tables can have multiple connections to each other. This requires an intermediate (pivot) table to manage the relationship.
Leaving our mother and children scenerio, lets adapt a more realistic example, Think of students and classes in a school.

  • A single student can enroll in multiple classes (Math, Science, English, etc.).
  • A single class can have many students enrolled.
  • This means that students have many classes, and classes have many students—this is a many-to-many relationship.

This type of relationship cannot be managed with just two tables. Instead, a third table, called a pivot table, is required to connect them.

To represent this, we need three tables:

  • students – Stores student details like id, name, and email.
  • classes – Stores class details like id, subject_name, and teacher_id.
  • student_class (Pivot Table) – Connects students and classes with student_id and class_id.

This pivot table ensures that any student can register for multiple classes while allowing each class to have multiple students. Representing this in a blogging platform, a Post can have many Tag records, and a Tag can be associated with many Post records. To implement this, you need three tables: the posts table, the tags table, and a pivot table like post_tag. The posts table might include columns like id, title, and content, while the tags table contains columns like id and name. The pivot table, post_tag, includes columns like post_id and tag_id, which act as foreign keys linking posts to tags. This setup allows you to easily retrieve all tags associated with a post or all posts associated with a specific tag, ensuring a flexible and scalable relationship between posts and tags.

Code Explanation and Output
In Eloquent, you define a many-to-many relationship using the belongsToMany method in both the Post and Tag models.

// Post Model
class Post extends Model {
    public function tags() {
        return $this->belongsToMany(Tag::class);
    }
}

// Tag Model
class Tag extends Model {
    public function posts() {
        return $this->belongsToMany(Post::class);
    }
}
Enter fullscreen mode Exit fullscreen mode

To retrieve all tags for a post, you can use the following code:

$post = Post::find(1);
$tags = $post->tags;
Enter fullscreen mode Exit fullscreen mode

Output
If the post with ID 1 has associated tags, $tags will be a collection of all tags linked to that post. If no tags exist, the collection will be empty

5. Has-One-Through Relationship
A has-one-through relationship is a type of relationship where a model is connected to another model through an intermediate model. This relationship is useful when you need to access data from a related table that is not directly connected to the primary table,
back to our mother and children example, Imagine a grandmother, a mother, and a child: The grandmother does not directly have a relationship with the grandchild, but she is connected through the mother.
If we want to find a grandchild's grandmother, we must go through the mother.

In another scenerio, a Supplier might have one History record through a User. The suppliers table might include columns like id and name, the users table might have columns like id, supplier_id, and name, and the histories table might include columns like id, user_id, and details. The supplier_id in the users table links suppliers to users, and the user_id in the histories table links users to their histories. This setup allows you to retrieve the history of a supplier by going through the user associated with that supplier, ensuring a clear and efficient relationship between suppliers and their histories.

Code Explanation and Output
In Eloquent, you define a has-one-through relationship using the hasOneThrough method in the Supplier model.

// Supplier Model
class Supplier extends Model {
    public function history() {
        return $this->hasOneThrough(History::class, User::class);
    }
}
Enter fullscreen mode Exit fullscreen mode

To retrieve the history of a supplier, you can use the following code:

$supplier = Supplier::find(1);
$history = $supplier->history;
Enter fullscreen mode Exit fullscreen mode

Output

If the supplier with ID 1 has an associated history through a user, $history will contain the history details. If no history exists, $history will be null.

6.Has-Many-Through Relationship
A has-many-through relationship is a type of relationship where a model is connected to multiple records in another model through an intermediate model. This relationship is useful when you need to access multiple related records that are not directly connected to the primary table.inotherwords, A has-many-through relationship is similar to a has-one-through, but instead of retrieving one related record, we retrieve multiple related records through another model.

For example, a Country might have many Post records through its User records. The countries table might include columns like id and name, the users table might have columns like id, country_id, and name, and the posts table might include columns like id, user_id, title, and content. The country_id in the users table links countries to users, and the user_id in the posts table links users to their posts. This setup allows you to retrieve all posts made by users from a specific country, ensuring a clear and efficient relationship between countries and their posts.

Code Explanation and Output
In Eloquent, you define a has-many-through relationship using the hasManyThrough method in the Country model.

// Country Model
class Country extends Model {
    public function posts() {
        return $this->hasManyThrough(Post::class, User::class);
    }
}
Enter fullscreen mode Exit fullscreen mode

To retrieve all posts from users in a country, you can use the following code:

$country = Country::find(1);
$posts = $country->posts;
Enter fullscreen mode Exit fullscreen mode

Output
If the country with ID 1 has users who have created posts, $posts will be a collection of all posts associated with users from that country. If no posts exist, the collection will be empty.

In conclusion, Eloquent relationships are a powerful Laravel feature that simplifies handling related data. Whether working with one-to-one or many-to-many relationships, Eloquent offers an intuitive and straightforward syntax for defining and querying associations. Mastering these relationships as a Laravel developer can significantly improve your workflow, making your code more efficient and easier to read.

Top comments (0)