Laravel 12 Eloquent: Relationships - A Complete Guide
Eloquent ORM (Object-Relational Mapping) is one of Laravel's most powerful features, allowing developers to interact with databases using an expressive, fluent syntax. One of the key strengths of Eloquent is its ability to define and manage relationships between database tables effortlessly.
In this blog post, we'll explore Laravel 12 Eloquent Relationships in detail, covering all types of relationships with practical examples.
Table of Contents
- Introduction to Eloquent Relationships
- Types of Eloquent Relationships
- Defining Relationships
- Querying Relationships
- Eager Loading
- Inserting Related Models
- Conclusion
1. Introduction to Eloquent Relationships
Database relationships define how tables interact with each other. In Laravel, Eloquent provides a simple way to define these relationships using model classes.
Relationships allow you to:
- Retrieve related data efficiently.
- Maintain data integrity.
- Simplify complex queries.
2. Types of Eloquent Relationships
Laravel supports several types of relationships:
🔹 One-to-One
A one-to-one relationship links one record in a table to exactly one record in another table.
Example: A User has one Profile.
Migration Setup
Schema::create('profiles', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained();
$table->string('bio');
$table->timestamps();
});
Defining the Relationship
// User Model
public function profile() {
return $this->hasOne(Profile::class);
}
// Profile Model
public function user() {
return $this->belongsTo(User::class);
}
Retrieving the Relationship
$user = User::find(1);
$profile = $user->profile; // Gets the user's profile
🔹 One-to-Many
A one-to-many relationship links one record to multiple records in another table.
Example: A Post has many Comments.
Migration Setup
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->foreignId('post_id')->constrained();
$table->text('content');
$table->timestamps();
});
Defining the Relationship
// Post Model
public function comments() {
return $this->hasMany(Comment::class);
}
// Comment Model
public function post() {
return $this->belongsTo(Post::class);
}
Retrieving the Relationship
$post = Post::find(1);
$comments = $post->comments; // Gets all comments for the post
🔹 Many-to-Many
A many-to-many relationship requires an intermediate pivot table.
Example: A User can belong to many Roles, and a Role can have many Users.
Migration Setup
Schema::create('role_user', function (Blueprint $table) {
$table->foreignId('user_id')->constrained();
$table->foreignId('role_id')->constrained();
$table->primary(['user_id', 'role_id']);
});
Defining the Relationship
// User Model
public function roles() {
return $this->belongsToMany(Role::class);
}
// Role Model
public function users() {
return $this->belongsToMany(User::class);
}
Retrieving the Relationship
$user = User::find(1);
$roles = $user->roles; // Gets all roles of the user
🔹 Has-One-Through
This relationship allows accessing a distant relation via an intermediate model.
Example: A Supplier has one History through a User.
Migration Setup
Schema::create('suppliers', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->foreignId('supplier_id')->constrained();
$table->string('name');
$table->timestamps();
});
Schema::create('histories', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained();
$table->string('details');
$table->timestamps();
});
Defining the Relationship
// Supplier Model
public function history() {
return $this->hasOneThrough(History::class, User::class);
}
Retrieving the Relationship
$supplier = Supplier::find(1);
$history = $supplier->history; // Gets the supplier's history via user
🔹 Has-Many-Through
Similar to hasOneThrough, but retrieves multiple records.
Example: A Country has many Posts through Users.
Migration Setup
Schema::create('countries', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->foreignId('country_id')->constrained();
$table->string('name');
$table->timestamps();
});
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained();
$table->string('title');
$table->timestamps();
});
Defining the Relationship
// Country Model
public function posts() {
return $this->hasManyThrough(Post::class, User::class);
}
Retrieving the Relationship
$country = Country::find(1);
$posts = $country->posts; // Gets all posts from users in the country
🔹 Polymorphic Relationships
A polymorphic relationship allows a model to belong to multiple other models on a single association.
Example: Comments can belong to Posts or Videos.
Migration Setup
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->text('content');
$table->morphs('commentable'); // Adds commentable_id and commentable_type
$table->timestamps();
});
Defining the Relationship
// Comment Model
public function commentable() {
return $this->morphTo();
}
// Post Model
public function comments() {
return $this->morphMany(Comment::class, 'commentable');
}
// Video Model
public function comments() {
return $this->morphMany(Comment::class, 'commentable');
}
Retrieving the Relationship
$post = Post::find(1);
$comments = $post->comments; // Gets all comments for the post
🔹 Many-to-Many Polymorphic Relationships
A more advanced polymorphic relationship where multiple models can have many related models.
Example: Posts and Videos can have many Tags.
Migration Setup
Schema::create('taggables', function (Blueprint $table) {
$table->foreignId('tag_id')->constrained();
$table->morphs('taggable'); // taggable_id, taggable_type
});
Defining the Relationship
// Tag Model
public function posts() {
return $this->morphedByMany(Post::class, 'taggable');
}
public function videos() {
return $this->morphedByMany(Video::class, 'taggable');
}
// Post Model
public function tags() {
return $this->morphToMany(Tag::class, 'taggable');
}
// Video Model
public function tags() {
return $this->morphToMany(Tag::class, 'taggable');
}
Retrieving the Relationship
$post = Post::find(1);
$tags = $post->tags; // Gets all tags for the post
3. Defining Relationships
All relationships in Laravel are defined as methods in Eloquent models. The method names should be descriptive (e.g., posts(), comments()).
4. Querying Relationships
You can query relationships like regular methods:
// Get all posts with at least one comment
$posts = Post::has('comments')->get();
// Get posts with more than 5 comments
$posts = Post::has('comments', '>', 5)->get();
// Filter using whereHas
$posts = Post::whereHas('comments', function ($query) {
$query->where('content', 'like', '%awesome%');
})->get();
5. Eager Loading
Eager loading prevents the N+1 query problem by loading relationships in advance.
// Without Eager Loading (N+1 Problem)
$posts = Post::all();
foreach ($posts as $post) {
echo $post->comments->count(); // Queries the DB each time
}
// With Eager Loading (Optimized)
$posts = Post::with('comments')->get();
foreach ($posts as $post) {
echo $post->comments->count(); // No additional queries
}
6. Inserting Related Models
You can attach related models easily:
// One-to-Many
$post = Post::find(1);
$comment = $post->comments()->create(['content' => 'Great post!']);
// Many-to-Many
$user = User::find(1);
$user->roles()->attach([1, 2]); // Attach role IDs
7. Conclusion
Laravel Eloquent Relationships provide a clean, expressive way to handle database associations. Whether you're working with one-to-one, one-to-many, many-to-many, or polymorphic relationships, Eloquent makes it easy to define, query, and manage them efficiently.
By mastering these relationships, you can build complex database interactions with minimal effort while keeping your code clean and maintainable.
🚀 Happy Coding with Laravel 12! 🚀
Let me know in the comments if you have any questions! 👇😊
Projects related to this guide
Use the concepts from this article in practical source-code projects.
Flask Authentication System (Free Version) - Kritim Yantra
🛠 Features✔ Google & GitHub Authentication✔ User Registration & Login✔ Profile/Dashboard Access✔ Secure...
Python Flask Blog Project with Admin Panel
Are you ready to launch a powerful, modern, and fully customizable blog? Look no further! Introducing the Flask-...
Laravel 12 + ReactJS Starter Kit: Add Multi-Language Support (Arabic, English, Spanish) with Blog CRUD
🚀 Installation & Setup Download & Extract Get the ZIP from kritimyantra.com and extract it. Includes pr...
Comments
No comments yet. Be the first to comment.
Sign in to join the discussion.