HomeLARAVELLaravel Eloquent Relationships(ORM)-Full Topic Coverage

Laravel Eloquent Relationships(ORM)-Full Topic Coverage

βœ… 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

  1. One to One
  2. One to Many
  3. Many to Many
  4. Has One Through
  5. Has Many Through
  6. Polymorphic One to One
  7. Polymorphic One to Many
  8. 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 name

2. πŸ‘¨β€πŸ‘§ 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

MethodDescription
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

AdvantageExplanation
βœ… Readable & expressive syntaxEasy to define and use
βœ… Fewer queries with eager loadingAvoid N+1 problems
βœ… Chainable queriesMore flexible querying
βœ… Automatic foreign key conventionsReduces boilerplate
βœ… Relationship-based CRUDAttach/detach/sync/associate etc.
βœ… Maintains Data IntegrityWith cascade deletes and constraints

πŸ’‘ Tips & Best Practices

  1. Always eager load when accessing nested relationships.
  2. Use accessors/mutators with relationships for clean logic.
  3. Use withCount() for quick counts of related models.
  4. Prefer hasMany over manually writing joins.
  5. Use syncWithoutDetaching() to avoid losing previous pivot data.

Is Eloquent better than raw SQL?

It depends:
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?

By default, Eloquent converts the model name to a plural, snake_case table name.
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?

They protect against mass assignment vulnerabilities.
// Allow these fields for mass assignment
protected $fillable = [‘name’, ’email’];
// Block these fields (if using $guarded)
protected $guarded = [‘id’];

Does Eloquent support transactions?

Yes. Laravel supports database transactions using DB::beginTransaction(), commit(), and rollback().
DB::beginTransaction();
try {
// Do operations
DB::commit();
} catch (\Exception $e) {
DB::rollback();
}

Can I use Eloquent without Laravel?

Yes, but it requires some setup. Eloquent can be used as a standalone package in non-Laravel applications.

What is eager loading in Eloquent?

It loads relationships in a single query to prevent the N+1 problem.

// 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

What is lazy loading in Eloquent?

It loads relationships when accessed, not during the initial query. This may cause performance issues in loops.

Share:Β 

No comments yet! You be the first to comment.

Leave a Reply

Your email address will not be published. Required fields are marked *