From bd78f615d16015e7d28dae06adb893c3fb4fa4b7 Mon Sep 17 00:00:00 2001 From: Debangshu Roy Date: Thu, 20 Aug 2026 13:27:48 +0530 Subject: [PATCH 1/3] Lazy Loading Fixes for Laravel Forum * Modified scopeWithPostAndAuthorRelationships in Thread.php to eagerly load the category relation. * Updated DEFAULT_WITH in CategoryAccess.php to use newestThread.lastPost.thread and latestActiveThread.lastPost.thread. * Changed mount() in ThreadShow.php to manually execute $request->route('thread')->load('category') * Modified render() in PostShow.php to run $post->load('thread.category'). * Changed mount() in ThreadReply.php to eager load category. Replaced $this->thread->posts->find(...) with a database query $this->thread->posts()->find(...), ensuring we don't load the entire thread's post history into application memory. --- src/Http/Livewire/Pages/PostShow.php | 2 +- src/Http/Livewire/Pages/ThreadReply.php | 4 ++-- src/Http/Livewire/Pages/ThreadShow.php | 2 +- src/Models/Thread.php | 2 +- src/Support/Access/CategoryAccess.php | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Http/Livewire/Pages/PostShow.php b/src/Http/Livewire/Pages/PostShow.php index 49708c6b..bcc3811f 100644 --- a/src/Http/Livewire/Pages/PostShow.php +++ b/src/Http/Livewire/Pages/PostShow.php @@ -14,7 +14,7 @@ class PostShow extends Component { public function render(Request $request): View { - $post = $request->route('post'); + $post = $request->route('post')->load('thread.category'); if (!$post->isAccessibleTo($request->user())) { abort(404); diff --git a/src/Http/Livewire/Pages/ThreadReply.php b/src/Http/Livewire/Pages/ThreadReply.php index c5fd2e6b..326da62b 100644 --- a/src/Http/Livewire/Pages/ThreadReply.php +++ b/src/Http/Livewire/Pages/ThreadReply.php @@ -30,14 +30,14 @@ class ThreadReply extends Component public function mount(Request $request) { - $this->thread = $request->route('thread'); + $this->thread = $request->route('thread')->load('category'); if (!$this->thread->category->isAccessibleTo($request->user())) { abort(404); } if ($request->input('parent_id')) { - $this->parent = $this->thread->posts->find($request->input('parent_id')); + $this->parent = $this->thread->posts()->find($request->input('parent_id')); } UserCreatingPost::dispatch($request->user(), $this->thread); diff --git a/src/Http/Livewire/Pages/ThreadShow.php b/src/Http/Livewire/Pages/ThreadShow.php index 8a749ac2..b4bcb753 100644 --- a/src/Http/Livewire/Pages/ThreadShow.php +++ b/src/Http/Livewire/Pages/ThreadShow.php @@ -42,7 +42,7 @@ class ThreadShow extends EventfulPaginatedComponent public function mount(Request $request) { - $this->thread = $request->route('thread'); + $this->thread = $request->route('thread')->load('category'); if (!$this->thread->isAccessibleTo($request->user())) { abort(404); diff --git a/src/Models/Thread.php b/src/Models/Thread.php index be186194..4aea7cdf 100755 --- a/src/Models/Thread.php +++ b/src/Models/Thread.php @@ -90,7 +90,7 @@ public function scopeRecent(Builder $query): Builder public function scopeWithPostAndAuthorRelationships(Builder $query): Builder { - return $query->with('firstPost', 'lastPost', 'firstPost.author', 'lastPost.author', 'lastPost.thread', 'author'); + return $query->with('category', 'firstPost', 'lastPost', 'firstPost.author', 'lastPost.author', 'lastPost.thread', 'author'); } public function scopeOrdered(Builder $query): Builder diff --git a/src/Support/Access/CategoryAccess.php b/src/Support/Access/CategoryAccess.php index 35f5edb9..a5847d2c 100644 --- a/src/Support/Access/CategoryAccess.php +++ b/src/Support/Access/CategoryAccess.php @@ -15,7 +15,7 @@ class CategoryAccess { const DEFAULT_SELECT = ['*']; - const DEFAULT_WITH = ['newestThread', 'latestActiveThread', 'newestThread.lastPost', 'latestActiveThread.lastPost']; + const DEFAULT_WITH = ['newestThread', 'latestActiveThread', 'newestThread.lastPost.thread', 'latestActiveThread.lastPost.thread']; public static function getPrivateAncestor(?User $user, Category $category): ?Category { From 3452fd5b18ca5193aa62208d15c91cf30cfc618b Mon Sep 17 00:00:00 2001 From: Debangshu Roy Date: Fri, 21 Aug 2026 01:41:53 +0530 Subject: [PATCH 2/3] more Lazy Loading Fixes in components.post.card view calling isset($post->parent) and in post.card view accesses $post->thread->category->requiresPostApproval(), was triggering lazy loading --- src/Http/Livewire/Pages/PostShow.php | 2 +- src/Http/Livewire/Pages/PostsPendingApproval.php | 2 +- src/Http/Livewire/Pages/ThreadShow.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Http/Livewire/Pages/PostShow.php b/src/Http/Livewire/Pages/PostShow.php index bcc3811f..7660a63d 100644 --- a/src/Http/Livewire/Pages/PostShow.php +++ b/src/Http/Livewire/Pages/PostShow.php @@ -14,7 +14,7 @@ class PostShow extends Component { public function render(Request $request): View { - $post = $request->route('post')->load('thread.category'); + $post = $request->route('post')->load('thread.category', 'parent', 'parent.author', 'parent.thread.category'); if (!$post->isAccessibleTo($request->user())) { abort(404); diff --git a/src/Http/Livewire/Pages/PostsPendingApproval.php b/src/Http/Livewire/Pages/PostsPendingApproval.php index 98c96d82..05122ee0 100644 --- a/src/Http/Livewire/Pages/PostsPendingApproval.php +++ b/src/Http/Livewire/Pages/PostsPendingApproval.php @@ -34,7 +34,7 @@ protected function getPosts(Request $request): Collection ->notFirstInThread() ->pendingApproval() ->orderBy('created_at', 'desc') - ->with('thread', 'author'); + ->with('thread.category', 'author', 'parent', 'parent.author', 'parent.thread.category'); $accessibleCategoryIds = CategoryAccess::getFilteredIdsFor($request->user()); diff --git a/src/Http/Livewire/Pages/ThreadShow.php b/src/Http/Livewire/Pages/ThreadShow.php index b4bcb753..8b48509b 100644 --- a/src/Http/Livewire/Pages/ThreadShow.php +++ b/src/Http/Livewire/Pages/ThreadShow.php @@ -243,7 +243,7 @@ public function render(Request $request): View } $posts = $postsQuery - ->with('author', 'thread') + ->with('author', 'thread.category', 'parent', 'parent.author', 'parent.thread.category') ->orderBy('created_at', 'asc') ->paginate(); From 2fe8040a28603d7fc0fa87c06ec0417b41c1aea0 Mon Sep 17 00:00:00 2001 From: Debangshu Roy Date: Sat, 29 Aug 2026 00:42:42 +0530 Subject: [PATCH 3/3] Lazy load fix for Blade-tailwind preset Modified src/Http/Controllers/Blade/ThreadController.php so that when viewing a thread, the posts query eager loads parent, parent.author, parent.thread, and parent.thread.category. Modified src/Http/Controllers/Blade/PostController.php to explicitly load those same relationships when fetching a single post for viewing, editing, deleting, or restoring. --- src/Http/Controllers/Blade/PostController.php | 17 +++++++++++++---- src/Http/Controllers/Blade/ThreadController.php | 4 ++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Http/Controllers/Blade/PostController.php b/src/Http/Controllers/Blade/PostController.php index 721241c7..60db8b9e 100644 --- a/src/Http/Controllers/Blade/PostController.php +++ b/src/Http/Controllers/Blade/PostController.php @@ -28,6 +28,8 @@ public function show(Request $request): View abort(404); } + $post->load(['parent', 'parent.author', 'parent.thread', 'parent.thread.category']); + if ($request->user() !== null) { UserViewingPost::dispatch($request->user(), $post); } @@ -45,6 +47,10 @@ public function create(Request $request): View $post = $request->has('post_id') ? $thread->posts->find($request->input('post_id')) : null; + if ($post !== null) { + $post->load(['author', 'thread']); + } + return ViewFactory::make('forum::post.create', compact('thread', 'post')); } @@ -70,11 +76,12 @@ public function edit(Request $request): View } $this->authorize('edit', $post); - - UserEditingPost::dispatch($request->user(), $post); - + $thread = $post->thread; $category = $post->thread->category; + $post->load(['parent', 'parent.author', 'parent.thread', 'parent.thread.category']); + + UserEditingPost::dispatch($request->user(), $post); return ViewFactory::make('forum::post.edit', compact('category', 'thread', 'post')); } @@ -96,6 +103,7 @@ public function confirmDelete(Request $request): View { $thread = $request->route('thread'); $post = $request->route('post'); + $post->load(['parent', 'parent.author', 'parent.thread', 'parent.thread.category']); return ViewFactory::make('forum::post.confirm-delete', ['category' => $thread->category, 'thread' => $thread, 'post' => $post]); } @@ -104,6 +112,7 @@ public function confirmRestore(Request $request): View { $thread = $request->route('thread'); $post = $request->route('post'); + $post->load(['parent', 'parent.author', 'parent.thread', 'parent.thread.category']); return ViewFactory::make('forum::post.confirm-restore', ['category' => $thread->category, 'thread' => $thread, 'post' => $post]); } @@ -140,7 +149,7 @@ public function pendingApproval(Request $request): View ->notFirstInThread() ->pendingApproval() ->orderBy('created_at', 'desc') - ->with('thread', 'author'); + ->with('thread', 'thread.category', 'author', 'parent', 'parent.thread', 'parent.thread.category'); // Get accessible category IDs for the current user $accessibleCategoryIds = CategoryAccess::getFilteredIdsFor($request->user()); diff --git a/src/Http/Controllers/Blade/ThreadController.php b/src/Http/Controllers/Blade/ThreadController.php index 7b17b1b4..88203d33 100644 --- a/src/Http/Controllers/Blade/ThreadController.php +++ b/src/Http/Controllers/Blade/ThreadController.php @@ -121,7 +121,7 @@ public function show(Request $request): View } $posts = $postsQuery - ->with('author', 'thread') + ->with('author', 'thread', 'parent', 'parent.author', 'parent.thread', 'parent.thread.category') ->orderBy('created_at', 'asc') ->paginate(); @@ -303,7 +303,7 @@ public function pendingApproval(Request $request): View $threads = Thread::notDeleted() ->pendingApproval() ->orderBy('created_at', 'desc') - ->with('category', 'author', 'lastPost', 'lastPost.author', 'lastPost.thread'); + ->with('category', 'firstPost', 'author', 'lastPost', 'lastPost.author', 'lastPost.thread'); // Get accessible category IDs for the current user $accessibleCategoryIds = CategoryAccess::getFilteredIdsFor($request->user());