You're running into this issue because when you prepend the newly created $post to your $this->posts collection, that $post instance does not have its user relationship loaded. As a result, when you loop over $this->posts in your Blade view and access $post->user->name, Laravel will perform a query for each post that doesn't have the user relationship loaded, causing the N+1 problem.
Why does this happen?
- In
mount(), you eager load theuserrelationship:Post::query()->orderBy('created_at', 'desc')->with('user')->take(10)->get(); - In
createPost(), you create a new post, but the$postmodel returned fromcreate()does not have theuserrelationship loaded. - When you prepend this
$postto your$this->postscollection, only this new post is missing the relationship.
Solution
After creating the post, load its user relationship before prepending it to the collection.
Here's how you can do it:
public function createPost(): void
{
$this->authorize('create', Post::class);
$this->createPostForm->validate();
$post = auth()->user()->posts()->create(
$this->createPostForm->only('body')
);
$this->createPostForm->reset();
// Eager load the user relationship on the new post
$post->load('user');
// Prepend the new post to the collection
$this->posts->prepend($post);
// Optionally, if you want to keep only the latest 10 posts:
$this->posts = $this->posts->take(10);
}
Alternative: Always Reload the Collection
If you want to guarantee consistency (for example, if other users might create posts at the same time), you can always reload the collection after creating a post:
$this->posts = Post::query()
->orderBy('created_at', 'desc')
->with('user')
->take(10)
->get();
But for most cases, loading the relationship on the new post is sufficient and more efficient.
Summary:
Always ensure that any model you add to an eager-loaded collection also has the necessary relationships loaded. Use $post->load('user') before prepending.
Let me know if you need further clarification!