📖 Scenario: You are building a simple blog application using Laravel. Each blog post has many comments. You want to display a list of posts with their comments efficiently.
🎯 Goal: Learn how to set up Eloquent relationships and use lazy loading with eager loading to prevent the N+1 query problem.
📋 What You'll Learn
Create a Post model with a relationship to Comment model
Create a Comment model with a relationship to Post model
Write a query to get all posts with their comments using eager loading
Display posts with their comments without causing N+1 queries
💡 Why This Matters
🌍 Real World
Efficiently loading related data in Laravel applications is crucial for performance, especially when displaying lists with related items like posts and comments.
💼 Career
Understanding and preventing N+1 query problems is a key skill for Laravel developers to write optimized database queries and improve app speed.
Progress0 / 4 steps
1
Define the Post and Comment models with relationships
Create a Post model class with a comments() method that returns a hasMany relationship to the Comment model. Also create a Comment model class with a post() method that returns a belongsTo relationship to the Post model.
Laravel
Hint
Use hasMany in Post for comments and belongsTo in Comment for post.
2
Create a variable to hold all posts
In a controller or route closure, create a variable called $posts and assign it the result of Post::all() to get all posts without comments loaded yet.
Laravel
Hint
Use Post::all() to get all posts.
3
Use eager loading to load comments with posts
Modify the $posts variable assignment to use Post::with('comments')->get() so that comments are loaded eagerly with posts, preventing N+1 queries.
Laravel
Hint
Use with('comments') before get() to eager load.
4
Display posts with their comments in a Blade view
In a Blade template, use a @foreach loop to iterate over $posts. Inside it, display the post title and use another @foreach loop to display each comment's content from $post->comments. This shows how eager loading prevents N+1 queries.
Laravel
Hint
Use nested @foreach loops in Blade to display posts and their comments.
Practice
(1/5)
1. What is the main purpose of using with() in Laravel Eloquent queries?
easy
A. To delete related models automatically
B. To load related models eagerly and prevent the N+1 query problem
C. To delay loading related models until they are accessed
D. To paginate the main query results
Solution
Step 1: Understand lazy vs eager loading
Lazy loading delays loading related data until accessed, causing multiple queries (N+1 problem).
Step 2: Role of with()
The with() method loads related models eagerly in one query, preventing multiple queries.
Final Answer:
To load related models eagerly and prevent the N+1 query problem -> Option B
Quick Check:
Eager loading = with() usage [OK]
Hint: Use with() to load relations early and avoid many queries [OK]
Common Mistakes:
Confusing lazy loading with eager loading
Thinking with() delays loading
Assuming with() deletes data
Mixing with() with pagination
2. Which of the following is the correct syntax to eager load the 'comments' relation on a Post model?
easy
A. $posts = Post::with('comments')->get();
B. $posts = Post::load('comments')->get();
C. $posts = Post::eager('comments')->get();
D. $posts = Post::fetch('comments')->get();
Solution
Step 1: Identify Laravel eager loading method
Laravel uses with() to eager load relations, not load() or others in this context.
Step 2: Check method chaining and syntax
with('comments') is called before get() to eager load comments with posts.
Final Answer:
$posts = Post::with('comments')->get(); -> Option A
Quick Check:
Eager load syntax = with() before get() [OK]
Hint: Remember: with() before get() for eager loading [OK]
Common Mistakes:
Using load() statically instead of on model instance
Using non-existent methods like eager() or fetch()
Calling with() after get()
3. Given the code below, what will be the total number of database queries executed?
A. Incorrect relation name 'items', should be 'item'
B. Loop variable should be $orders not $order
C. Using with() causes lazy loading, should use load()
D. Missing get() after with() to execute the query
Solution
Step 1: Check query execution
Order::with('items') builds a query but does not execute it without get() or similar.
Step 2: Effect on foreach loop
Without get(), $orders is a query builder, not a collection, so foreach will error.
Final Answer:
Missing get() after with() to execute the query -> Option D
Quick Check:
Always call get() to run query after with() [OK]
Hint: Add get() after with() to fetch data [OK]
Common Mistakes:
Forgetting to execute query with get()
Assuming with() runs query immediately
Confusing relation names without checking model
Misunderstanding foreach variable naming
5. You want to display a list of authors with their books and each book's reviews without causing N+1 queries. Which is the best way to write the query?
hard
A. $authors = Author::with('reviews')->get();
B. $authors = Author::with('books')->get(); foreach ($authors as $author) { $author->books->load('reviews'); }
C. $authors = Author::with('books.reviews')->get();
D. $authors = Author::all(); foreach ($authors as $author) { foreach ($author->books as $book) { echo $book->reviews->count(); } }
Solution
Step 1: Understand nested eager loading
To avoid N+1, load related models and their relations in one query using dot notation.
Step 2: Analyze options for efficiency
$authors = Author::with('books.reviews')->get(); uses with('books.reviews') to eager load books and their reviews together, preventing multiple queries.
Final Answer:
$authors = Author::with('books.reviews')->get(); -> Option C
Quick Check:
Nested eager loading = dot notation in with() [OK]
Hint: Use dot notation in with() for nested relations [OK]
Common Mistakes:
Loading relations inside loops causing N+1
Not eager loading nested relations together
Using wrong relation names
Assuming with('reviews') loads nested reviews
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.