DEV Community

Cover image for Laravel - Advanced Eloquent ORM Techniques
Babalola Macaulay
Babalola Macaulay

Posted on

Laravel - Advanced Eloquent ORM Techniques

Laravel's Eloquent ORM is a very powerful took for interacting with databases, using an expressive fluent syntax. While it's very easy to get quite familiar with the basics of Eloquent and stick to using just the basic techniques, there are advanced techniques that can significantly enhance your application's efficiency and capabilities.

In this article, I will be talking about these advanced Eloquent ORM techniques, helping you make the most of Laravel's strongly built database interaction layer.

1. Complex Query Building

Eloquent provides a clean and simple way to build complex SQL queries, beyond just basic CRUD operations. You can use advanced query-building techniques to optimize your database interactions using Subqueries and Advance Where Clauses.

SubQueries

use App\Models\Order;
use App\Models\User;

$latestOrders = Order::select('user_id', 'created_at')
    ->where('created_at', function ($query) {
        $query->selectRaw('MAX(created_at)')
            ->from('orders')
            ->groupBy('user_id');
    })
    ->get();

$users = User::whereIn('id', $latestOrders->pluck('user_id'))->get();
Enter fullscreen mode Exit fullscreen mode

Advanced Where Clauses

$users = User::where('status', 'active')
    ->where(function ($query) {
        $query->where('age', '>', 30)
            ->orWhere('country', 'US');
    })
    ->get();
Enter fullscreen mode Exit fullscreen mode

2. Relationships and Performance Optimization

Eloquent makes it easy to define relationships between models. However, optimizing these relationships is crucial for performance.

Eager Loading

This helps to reduce the number of queries executed by loading related models alongside the main model.

$users = User::with('posts', 'comments')->get();
Enter fullscreen mode Exit fullscreen mode

Lazy Eager Loading

Sometimes, you might want to load relationships after the initial query. Lazy eager loading can help in such scenarios.

$users = User::all();
if ($someCondition) {
    $users->load('posts', 'comments');
}
Enter fullscreen mode Exit fullscreen mode

Chunking

For processing large datasets, chunking can help avoid memory exhaustion by breaking the query results into manageable chunks.

User::chunk(100, function ($users) {
    foreach ($users as $user) {
        // Process user
    }
});
Enter fullscreen mode Exit fullscreen mode

3. Advanced Relationships

Polymorphic Relationships

Polymorphic relationships allow a model to belong to more than one other model on a single association.

// Migration for comments table
Schema::create('comments', function (Blueprint $table) {
    $table->id();
    $table->text('body');
    $table->morphs('commentable');
    $table->timestamps();
});

// Comment model
class Comment extends Model {
    public function commentable() {
        return $this->morphTo();
    }
}

// Post model
class Post extends Model {
    public function comments() {
        return $this->morphMany(Comment::class, 'commentable');
    }
}

// Video model
class Video extends Model {
    public function comments() {
        return $this->morphMany(Comment::class, 'commentable');
    }
}
Enter fullscreen mode Exit fullscreen mode

Many-to-Many Polymorphic Relationships

Many-to-many polymorphic relationships allow a model to belong to multiple other models and vice versa.

// Migration for tags table
Schema::create('tags', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->timestamps();
});

// Migration for taggables table
Schema::create('taggables', function (Blueprint $table) {
    $table->id();
    $table->foreignId('tag_id')->constrained();
    $table->morphs('taggable');
    $table->timestamps();
});

// Tag model
class Tag extends Model {
    public function posts() {
        return $this->morphedByMany(Post::class, 'taggable');
    }

    public function videos() {
        return $this->morphedByMany(Video::class, 'taggable');
    }
}

// Post model
class Post extends Model {
    public function tags() {
        return $this->morphToMany(Tag::class, 'taggable');
    }
}

// Video model
class Video extends Model {
    public function tags() {
        return $this->morphToMany(Tag::class, 'taggable');
    }
}
Enter fullscreen mode Exit fullscreen mode

Mastering advanced Eloquent ORM techniques can significantly enhance your Laravel application's performance and maintainability.
By leveraging complex query building, optimizing relationships, understanding advanced relationships, and a few other Advanced Eloquent ORM Techniques in Laravel, you can build more efficient and scalable applications.

Cheers 🥂

Top comments (0)