β What are Eloquent Relationships?
ORM (Object-Relational Mapping) is a programming technique that allows you to interact with a relational database using object-oriented code instead of raw SQL queries.
Laravel Eloquent is Laravel’s built-in ORM that provides an ActiveRecord implementation, allowing each database table to have a corresponding Model that interacts with that table..
πΉ In simple terms:
Eloquent lets you interact with your database using PHP classes and objects instead of writing raw SQL queries.
Eloquent relationships are a way of defining relationships between models in Laravel. They provide an easy, readable, and efficient way to interact with related data using Laravelβs ORM (Object-Relational Mapping).
π Types of Relationships in Laravel
- One to One
- One to Many
- Many to Many
- Has One Through
- Has Many Through
- Polymorphic One to One
- Polymorphic One to Many
- Polymorphic Many to Many (morphToMany & morphedByMany)
1. π§ One to One
πΉ Example:
A user has one profile.
A one-to-one relationship is used when one record in a table is associated with one record in another table.
Migration:
Schema::create('profiles', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->string('bio');
});
Model:
// User.php
public function profile()
{
return $this->hasOne(Profile::class); // if you already set foreign_key
}
/*public function profile()
{
return $this->hasOne(Profile::class,'profile_id_fk','id');
// $this->hasOne(Profile::class,'foreign_key',local_key');
}*/
// Profile.php
public function user()
{
return $this->belongsTo(User::class);
}Usage:
$user = User::find(1);
echo $user->profile->bio;
//OR
$user = User::with('profile')->get(); // profile is function name2. π¨βπ§ One to Many
πΉ Example:
A post has many comments.
A one-to-many relationship is used when one record in a table has many related records in another table.
Model:
// Post.php
public function comments()
{
return $this->hasMany(Comment::class);
}
// Comment.php
public function post()
{
return $this->belongsTo(Post::class);
}Usage:
$post = Post::find(1);
foreach ($post->comments as $comment) {
echo $comment->body;
}3. π¬ Many to Many
πΉ Example:
A user can have many roles and a role can belong to many users.
A many-to-many relationship is used when each record in one table may be related to many records in another table and vice versa.
This needs a pivot table (like role_user).
Pivot Table Migration:
Schema::create('role_user', function (Blueprint $table) {
$table->foreignId('user_id')->constrained();
$table->foreignId('role_id')->constrained();
});Model:
// User.php
public function roles()
{
return $this->belongsToMany(Role::class);
}
// Role.php
public function users()
{
return $this->belongsToMany(User::class);
}Usage:
$user->roles()->attach($roleId);
$user->roles()->detach($roleId);
$user->roles()->sync([1, 2, 3]);4. π Has One Through
πΉ Example:
A country has one government, through a state.
A “has-one-through” relationship provides a shortcut for accessing a model through an intermediate relation.
Model:
// Country.php
public function government()
{
return $this->hasOneThrough(Government::class, State::class);
}5. π Has Many Through
πΉ Example:
A country has many posts through states.
In Laravel, the hasManyThrough relationship is used to define a “has-many-through” connection between two models that do not have a direct relationship, but are linked through a third model.
Model:
// Country.php
public function posts()
{
return $this->hasManyThrough(Post::class, State::class);
}
// country belongs to state
// state belongs to posts
// not direct relationship between post and country
//Country -> hasMany(State)
//State -> hasMany(Post)
/* So:
πΉ A Country has many States
πΉ Each State has many Posts
πΉ Therefore, a Country has many Posts through States */
π Optional: If your foreign/primary keys are not standard, specify them manually:
return $this->hasManyThrough(
Post::class, // Final model
State::class, // Intermediate model
'country_id', // Foreign key on states table
'state_id', // Foreign key on posts table
'id', // Local key on countries table
'id' // Local key on states table
);6. π Polymorphic One to One
πΉ Example:
An image can belong to either a user or a post.
Used when different models can share the same related model.
Migration:
Schema::create('images', function (Blueprint $table) {
$table->id();
$table->morphs('imageable');
$table->string('url');
});Model:
// Image.php
public function imageable()
{
return $this->morphTo();
}
// Post.php or User.php
public function image()
{
return $this->morphOne(Image::class, 'imageable');
}7. πΈ Polymorphic One to Many
πΉ Example:
A comment can belong to both posts and videos.
Used when different models can share the same related model.
Model:
// Comment.php
public function commentable()
{
return $this->morphTo();
}
// Post.php or Video.php
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}8. π Polymorphic Many to Many
πΉ Example:
A tag can belong to posts or videos.
A model can belong to multiple models on a single association.
Model:
// Tag.php
public function posts()
{
return $this->morphedByMany(Post::class, 'taggable');
}
public function videos()
{
return $this->morphedByMany(Video::class, 'taggable');
}
// Post.php or Video.php
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}π¦ Eager Loading Relationships
$posts = Post::with('comments')->get();β Benefit:
Avoids N+1 Query Problem, improves performance.
π§ Relationship Methods
| Method | Description |
|---|---|
hasOne() | One-to-One |
hasMany() | One-to-Many |
belongsTo() | Child side of one-to-one/many |
belongsToMany() | Many-to-Many |
morphTo() | Polymorphic Parent |
morphOne() | One-to-One Polymorphic |
morphMany() | One-to-Many Polymorphic |
morphToMany() | Many-to-Many Polymorphic |
morphedByMany() | Inverse of morphToMany |
π’ Advantages of Eloquent Relationships
| Advantage | Explanation |
|---|---|
| β Readable & expressive syntax | Easy to define and use |
| β Fewer queries with eager loading | Avoid N+1 problems |
| β Chainable queries | More flexible querying |
| β Automatic foreign key conventions | Reduces boilerplate |
| β Relationship-based CRUD | Attach/detach/sync/associate etc. |
| β Maintains Data Integrity | With cascade deletes and constraints |
π‘ Tips & Best Practices
- Always eager load when accessing nested relationships.
- Use accessors/mutators with relationships for clean logic.
- Use
withCount()for quick counts of related models. - Prefer
hasManyover manually writing joins. - Use
syncWithoutDetaching()to avoid losing previous pivot data.
Is Eloquent better than raw SQL?
Use Eloquent for rapid development, simplicity, and readability.
Use raw SQL or Query Builder for complex joins or performance-sensitive queries.
How does Eloquent know which table to use?
E.g.,
User model β users table.You can override it using:
protected $table = ‘custom_table_name’;
What is the use of $fillable and $guarded in Eloquent?
// Allow these fields for mass assignment
protected $fillable = [‘name’, ’email’];
// Block these fields (if using $guarded)
protected $guarded = [‘id’];
Does Eloquent support transactions?
DB::beginTransaction(), commit(), and rollback().DB::beginTransaction();
try {
// Do operations
DB::commit();
} catch (\Exception $e) {
DB::rollback();
}
Can I use Eloquent without Laravel?
What is eager loading in Eloquent?
// Without eager loading
$posts = Post::all(); // Will run a separate query for each post’s user
// With eager loading
$posts = Post::with(‘user’)->get(); // Optimized
