Laravel eloquent - One to many relationships
I hope you will find these tips useful.
On the post model rename the categories
function to category
. A belongs_to
relation is singular, so this post has one and only one category.
Relations also have a short hand, this shorthand syntax is useful because it is cleaner to use and the results are cached. Heres an example:
$category = Category::find(1);
foreach($category->posts as post) {
echo $post->title;
}
Now an example of how to get all the posts with their related categories:
$posts = Post::all();
foreach($posts as $post) {
echo $post->category->name;
}
Now one thing you will quickly notice when doing this second example is the number of queries increase for each post you have. This is called the N+1 effect. Example, if you have 5 posts, one query will be executed to get those posts. Then in the loop we are executing a query to get the category. This results in 6 total queries.
To solve this problem, use eager loading, which reduces those 6 queries in our example down to 2.
$posts = Post::with('category')->all();
foreach($posts as $post) {
echo $post->category->name;
}
I hope that helps!
Related videos on Youtube
Allister
Updated on June 25, 2022Comments
-
Allister almost 2 years
I have just got started with laravel v3 and am trying to wrap my head around eloquent's One-To-Many relationships by creating a blog, I have posts that have a many to one relationship with categories (Each Post is linked to a category).
I have the following tables with the following fields:
posts: id, title, body, date_created, category_id
categories: id, name
I have the following two models:
class Category extends Eloquent { public function posts() { return $this->has_many('Post'); } } class Post extends Eloquent { public function categories() { return $this->belongs_to('Category'); } }
I figured out how to get all posts by passing in a category id:
category::find(2)->posts()->get())
I just need help on finding out how to get all posts, and get their corrisponding categories. So at the end of the day in the view I can output something like this:
{$post->title} - Category: {$post->category->name}
Thanks for any help!
-
Allister over 11 yearsThanks William that is just what I needed!
-
harishannam almost 11 yearsHope this is same with Laravel 4 too. I have one small doubt. I am new to this. Can you tell whether this eager loading has to be typed in controller / view?
-
William Cahill-Manley almost 11 yearsTypicly this would be done in a controller, or a wrapper class known as a repository which is used by the controller. You should never do it in the view. Also all of this has stayed the same in L4 as far as I can tell.