Eloquent Constrained Relations
Eloquent Constrained Relations
Eloquent Constrained Relations
Tip: Constrained Eager Loading
Post::with(['comments' => fn($q) => $q->where('approved', true)])->get();
Gotcha: whereHas vs with
whereHas filters parent models. with loads related models. They serve different purposes.
Tip: has() for Existence
Post::has('comments')->get();
Posts that have at least one comment.
Gotcha: withCount with Constraints
Post::withCount(['comments' => fn($q) => $q->where('approved', true)])->get();
Tip: whereRelation
Post::whereRelation('author', 'active', true)->get();
Shorthand for whereHas.
Gotcha: Multiple Constraints
Post::with(['comments' => fn($q) => $q->approved()->latest()->limit(5)])->get();
Tip: Use cursor() for Memory-Neutral Iteration
When exporting 100K rows, get() loads everything into memory. cursor() uses yield and keeps memory flat regardless of row count. Perfect for artisan commands.
Tip: Pivot Data Is Read-Only by Default
Many-to-many pivot columns are read-only unless you define custom pivot models. Use ->withPivot('expires_at') to make them accessible, and newPivot() to make them writable.
Gotcha: touch() Fires Multiple Queries
Calling touch() on a model updates the updated_at of ALL related models in the relationship chain. This can cascade into dozens of unnecessary writes.
Senior Insight
The constrained() method on foreign key definitions makes migrations cleaner, but it has a gotcha: it uses the table name by convention, which may not match the actual foreign key target. I've seen migrations fail because constrained() guessed the wrong table name from a non-standard foreign key column. Always verify the table name constrained() resolves to, and when in doubt, be explicit: constrained('actual_table_name').
Source: Laravel Docs (https://laravel.com/docs/eloquent), Laravel News (https://laravel-news.com/), Freek.dev (https://freek.dev/tags/eloquent)