
December 05, 2025
Table of Contents
Laravel’s Eloquent ORM remains one of the most expressive and powerful ActiveRecord implementations in modern PHP frameworks. But as applications grow — especially large SaaS platforms, enterprise systems, or domain-driven architectures — developers quickly discover that basic Eloquent usage is not enough.
To build complex applications, you must master:
Advanced relationship handling
Efficient query optimization
Polymorphic structures
Data pipelines
DTO mapping
Model events & observers
Attribute casting & value objects
Query customization using macros
Multi-tenancy considerations
Repository + domain patterns
Chunking, cursoring, caching strategies
Raw expressions and subqueries
Aggregate and analytical queries
This guide dives deeply into advanced Eloquent techniques used by senior Laravel engineers when handling high-performance, domain-rich, multi-layered applications.
1. Advanced Relationship Techniques
Eloquent relationships become extremely powerful when you use them beyond the basics.
a. Using Subqueries Inside Relationships
Example: Include latest order on each customer:
$customers = Customer::addSelect([ 'latest_order_total' => Order::select('total') ->whereColumn('customer_id', 'customers.id') ->latest() ->limit(1) ])->get();This prevents N+1 problems without eager loading.
b. Constraining Eager Loads
Load only active subscriptions:
User::with(['subscriptions' => function ($q) { $q->where('status', 'active'); }])->get();c. Loading Relationship Counts With Conditions
User::withCount(['orders as high_value_orders_count' => function ($q) { $q->where('total', '>', 500); }])->get();This is essential in dashboards and analytics.
2. Polymorphic Relationship Power
Polymorphic relations become necessary in large systems where multiple entities share common features.
Example: Comments on Posts, Videos, Events
public function commentable() { return $this->morphTo(); }Advanced polymorphic usage includes:
Polymorphic many-to-many for tagging
Polymorphic nested structures
Polymorphic pivot tables
Polymorphic Many-to-Many Tagging System
public function tags() { return $this->morphToMany(Tag::class, 'taggable'); }This allows one tagging table for dozens of entities.
3. Using Custom Pivot Models
Pivot tables often need additional fields like:
status
role
metadata
permission levels
Define a custom Pivot model:
class Membership extends Pivot { protected $casts = [ 'joined_at' => 'datetime', 'metadata' => 'array', ]; }Attach to relationship:
public function memberships() { return $this->belongsToMany(Team::class) ->using(Membership::class) ->withTimestamps(); }4. Value Object Casting & Custom Casts
Large applications benefit from rich data types, not just primitive values.
Example: Casting a Money value object:
class MoneyCast implements CastsAttributes { public function get($model, $key, $value) { return new Money($value); } public function set($model, $key, $value) { return $value->amount(); } }Model:
protected $casts = [ 'balance' => MoneyCast::class ];This yields cleaner domain-driven code.
5. Attribute Transformers (Accessors & Mutators)
Eloquent's attribute methods help structure domain rules.
Example: Encrypting sensitive fields:
protected function ssn(): Attribute { return Attribute::make( get: fn ($value) => decrypt($value), set: fn ($value) => encrypt($value) ); }6. Query Scopes for Cleaner Query Logic
Example: Shared logic for active tenants:
public function scopeActive($query) { return $query->where('status', 'active'); }Chainable:
Tenant::active()->where('plan', 'pro')->get();7. Repository Pattern Done Properly
In large domain-driven architectures, isolate business logic from Eloquent models.
Example:
class UserRepository { public function findWithOrders($id) { return User::with('orders')->findOrFail($id); } }Best used in enterprise layers, DDD, microservices, and SaaS.
8. Avoiding N+1 Queries: Advanced Techniques
a. Using loadMissing() to conditionally load relationships
$user->loadMissing('profile');b. Using lazy() & cursor() for large datasets
Efficient memory handling:
foreach (User::cursor() as $user) { // }c. Using chunkById() for scalable batch processing
User::chunkById(100, function ($users) { // });9. Raw Expressions & Analytical Queries
For reporting-heavy applications:
Using DB::raw in a Select
User::select( 'name', DB::raw('COUNT(*) OVER () as total_users') )->get();Using Subqueries for Ranking
User::select( 'name', DB::raw('row_number() over(order by points desc) as rank') )->get();10. JSON Columns & Advanced Querying
Modern databases like MySQL 8/PostgreSQL support JSON querying.
Example: Querying inside JSON:
User::where('settings->theme', 'dark')->get();Updating JSON keys:
$user->update([ 'settings->notifications->email' => false ]);JSON is essential for dynamic schemas in SaaS apps.
11. Model Observers for Domain Events
Observers centralize lifecycle logic.
Examples:
Automatically creating profile when user registers
Generating tenant resources
Syncing logs to external services
class UserObserver { public function created(User $user) { Profile::create(['user_id' => $user->id]); } }Register:
User::observe(UserObserver::class);Observers enforce consistency across all models.
12. Model Events + Queues for Heavy Lifting
Example: Processing image uploads asynchronously:
protected static function booted() { static::created(fn($post) => ProcessPostImages::dispatch($post) ); }Large SaaS apps rely heavily on this architecture.
13. Eloquent Macros for Custom ORM Methods
Extend Eloquent globally:
Builder::macro('whereLike', function ($column, $value) { return $this->where($column, 'LIKE', "%{$value}%"); });Usage:
User::whereLike('email', '@gmail.com')->get();Macros help enforce organization-wide query patterns.
14. Using Eloquent with Multi-Tenancy
Isolation patterns:
Global Scope:
protected static function booted() { static::addGlobalScope('tenant', function (Builder $builder) { $builder->where('tenant_id', tenant('id')); }); }OR using stancl/tenancy model separation:
CentralModelTenantModel
Allows per-tenant DB isolation.
15. Caching Eloquent Queries: Best Practices
Never cache full Eloquent models with relationships blindly.
Cache primitives:
Cache::remember("user:{$id}", 3600, fn() => User::select('id','name','email')->find($id) );Cache heavy computations:
Cache::remember('reports:monthly', 7200, fn() => ReportService::generate() );16. Pipelines + Eloquent = Clean Query Builders
Example: Apply filters dynamically:
app(Pipeline::class) ->send(User::query()) ->through([ Filters\Active::class, Filters\Role::class, Filters\DateRange::class ]) ->thenReturn() ->paginate();This pattern powers advanced admin dashboards and marketplaces.
Conclusion
Mastering advanced Eloquent concepts is essential when building large-scale, data-heavy, domain-driven, multi-tenant, or enterprise Laravel applications.
Eloquent is far more than a simple ORM — when used properly, it becomes a powerful domain modeling tool that handles:
complex relational data
high-performance queries
structured domain logic
scalable architecture patterns
expressive business rules
To continue mastering high-level Laravel architecture, explore more guides from an expert web developer in Nepal who specializes in scalable backend engineering and SaaS systems.

