Anonymous
Что является причиной того, что в моем приложении для ведения блогов Laravel 8 не отображаются все комментарии к статьям
Сообщение
Anonymous » 12 окт 2025, 11:22
Я работаю над приложением для ведения блога (ссылка на запрос на извлечение GitHub) в Laravel 8.
В app\Http\Controllers\ArticlesController.php у меня есть методы для отображения сведений о статье с включенными комментариями:
Код: Выделить всё
class ArticlesController extends FrontendController
{
protected $per_page = 12;
protected $comments_per_page = 10;
protected $comments_orderby_direction = 'desc';
public function show($slug)
{
$article = Article::visible()->where('slug', $slug)->firstOrFail();
// Throttle views
$sessionKey = 'article_viewed_' . $article->id;
$lastViewedAt = session($sessionKey);
if (!$lastViewedAt || Carbon::createFromTimestamp($lastViewedAt)->diffInMinutes(now()) >= 60) {
$article->increment('views');
session()->put($sessionKey, now()->timestamp);
}
// Older article
$old_article = Article::visible()
->where(function ($q) use ($article) {
$q->where('published_at', '', $article->published_at)
->orWhere(function ($q2) use ($article) {
$q2->where('published_at', $article->published_at)
->where('id', '>', $article->id);
});
})
->orderBy('published_at', 'asc')
->orderBy('id', 'asc')
->first();
// Approved top-level comments with approved replies
$comments = Comment::where('article_id', $article->id)
->where('approved', 1)
->whereNull('parent_id')
->with(['replies' => function ($query) {
$query->where('approved', 1);
}])
->orderBy('id', 'desc')
->get();
$comments_count = $comments->count();
return view(
'themes/' . $this->theme_directory . '/templates/single',
array_merge($this->data, [
'categories' => $this->article_categories,
'article' => $article,
'old_article' => $old_article,
'new_article' => $new_article,
'comments' => $comments,
'comments_count' => $comments_count,
'comments_per_page' => $this->comments_per_page,
'tagline' => $article->title,
'is_infinitescroll' => false
])
);
}
public function get_comments_ajax(Request $request)
{
if (!$request->ajax()) exit();
$article_id = $request->post('article_id');
$page_number = $request->post('page');
$offset = $this->comments_per_page * $page_number;
$more_comments_to_display = true;
$data['comments'] = $this->get_commentQuery($article_id, $this->comments_per_page, $offset)->get();
$content = '';
if ($data['comments']->count()) {
$content .= view(
'themes/' . $this->theme_directory . '/partials/comments-list',
array_merge($data, [
'is_infinitescroll' => $this->is_infinitescroll,
'theme_directory' => $this->theme_directory,
'article_id' => $article_id
])
);
} else {
$more_comments_to_display = false;
}
echo json_encode([
'html' => $content,
'page' => $page_number,
'more_comments_to_display' => $more_comments_to_display,
'article_id' => $article_id
]);
exit();
}
private function get_commentQuery(int $article_id, int $limit = 0, int $offset = 0): object
{
$commentQuery = Comment::where(['article_id' => $article_id, 'approved' => 1])
->orderBy('id', $this->comments_orderby_direction)
->with(['replies' => function ($query) {
$query->where('approved', 1);
}]);
if ($offset > 0) $commentQuery = $commentQuery->offset($offset);
if ($limit > 0) $commentQuery = $commentQuery->limit($limit);
return $commentQuery;
}
}
Модель комментариев:
Код: Выделить всё
class Comment extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'article_id',
'parent_id',
'body',
'approved'
];
// Join users to comments
public function user() {
return $this->belongsTo(User::class);
}
// Join articles to comments
public function article() {
return $this->belongsTo(Article::class);
}
// Join comment replies to comments
public function replies() {
return $this->hasMany(Comment::class, 'parent_id');
}
}
Список комментариев (и ответов) Blade:
Код: Выделить всё
@if ($comments && count($comments))
@foreach ($comments as $comment)
@if (is_null($comment->parent_id))
[i]user->avatar) }}"
alt="{{ $comment->user->first_name }} {{ $comment->user->last_name }}"
class="rounded-circle me-1">
{{ $comment->user->first_name }} {{ $comment->user->last_name }} says:
{{ date('jS M Y', strtotime($comment->created_at)) }}
{{ $comment->body }}
[list]
@if (Auth::check() && $comment->user->id !== Auth::id())
[*]
[/i]
@endif
@if (Auth::check() && $comment->user->id === Auth::id())
[*]
[i][/i]
[*]
@include(
'themes/' . $theme_directory . '/partials/comment-delete-form',
['commentOrReply' => $comment]
)
@endif
[/list]
{{-- Edit form --}}
@include('themes/' . $theme_directory . '/partials/comment-edit-form', [
'commentOrReply' => $comment,
])
{{-- Reply form --}}
@if (Auth::check())
@include('themes/' . $theme_directory . '/partials/comment-form', [
'article' => $article,
'parent_id' => $comment->id,
])
@endif
{{-- Replies --}}
@if ($comment->replies && count($comment->replies))
@foreach ($comment->replies as $reply)
[i]user->avatar) }}"
alt="{{ $reply->user->first_name }} {{ $reply->user->last_name }}"
class="rounded-circle me-1">
{{ $reply->user->first_name }} {{ $reply->user->last_name }} says:
{{ date('jS M Y', strtotime($reply->created_at)) }}
{{ $reply->body }}
[list]
@if (Auth::check() && $reply->user->id === Auth::id())
[*]
[/i]
[*]
@include(
'themes/' .
$theme_directory .
'/partials/comment-delete-form',
['commentOrReply' => $reply]
)
@endif
[/list]
{{-- Edit form --}}
@include(
'themes/' . $theme_directory . '/partials/comment-edit-form',
['commentOrReply' => $reply]
)
@endforeach
@endif
@endif
@endforeach
@endif
Проблема
Когда загрузка комментариев при прокрутке страницы через AJAX
отключена (для этого у меня есть опция в разделе «Настройки» CMS), по причине, которую я не смог обнаружить, загружаются не все комментарии и ответы к статьям, хотя я одобрил все комментарии, относящиеся к проверенной мной статье.
Я подозреваю, что ошибка находится в ArticlesController, но мне не удалось ее обнаружить.
Этот шаг кажется излишним, поскольку уже существует метод get_commentQuery:
Код: Выделить всё
// Approved top-level comments with approved replies
$comments = Comment::where('article_id', $article->id)
->where('approved', 1)
->whereNull('parent_id')
->with(['replies' => function ($query) {
$query->where('approved', 1);
}])
->orderBy('id', 'desc')
->get();
В чем причина этой ошибки?
Каков наиболее надежный способ ее исправить?
Подробнее здесь:
https://stackoverflow.com/questions/797 ... 8-blogging
1760257330
Anonymous
Я работаю над приложением для ведения блога (ссылка на запрос на извлечение GitHub) в Laravel 8. В app\Http\Controllers\ArticlesController.php у меня есть методы для отображения сведений о статье с включенными комментариями: [code]class ArticlesController extends FrontendController { protected $per_page = 12; protected $comments_per_page = 10; protected $comments_orderby_direction = 'desc'; public function show($slug) { $article = Article::visible()->where('slug', $slug)->firstOrFail(); // Throttle views $sessionKey = 'article_viewed_' . $article->id; $lastViewedAt = session($sessionKey); if (!$lastViewedAt || Carbon::createFromTimestamp($lastViewedAt)->diffInMinutes(now()) >= 60) { $article->increment('views'); session()->put($sessionKey, now()->timestamp); } // Older article $old_article = Article::visible() ->where(function ($q) use ($article) { $q->where('published_at', '', $article->published_at) ->orWhere(function ($q2) use ($article) { $q2->where('published_at', $article->published_at) ->where('id', '>', $article->id); }); }) ->orderBy('published_at', 'asc') ->orderBy('id', 'asc') ->first(); // Approved top-level comments with approved replies $comments = Comment::where('article_id', $article->id) ->where('approved', 1) ->whereNull('parent_id') ->with(['replies' => function ($query) { $query->where('approved', 1); }]) ->orderBy('id', 'desc') ->get(); $comments_count = $comments->count(); return view( 'themes/' . $this->theme_directory . '/templates/single', array_merge($this->data, [ 'categories' => $this->article_categories, 'article' => $article, 'old_article' => $old_article, 'new_article' => $new_article, 'comments' => $comments, 'comments_count' => $comments_count, 'comments_per_page' => $this->comments_per_page, 'tagline' => $article->title, 'is_infinitescroll' => false ]) ); } public function get_comments_ajax(Request $request) { if (!$request->ajax()) exit(); $article_id = $request->post('article_id'); $page_number = $request->post('page'); $offset = $this->comments_per_page * $page_number; $more_comments_to_display = true; $data['comments'] = $this->get_commentQuery($article_id, $this->comments_per_page, $offset)->get(); $content = ''; if ($data['comments']->count()) { $content .= view( 'themes/' . $this->theme_directory . '/partials/comments-list', array_merge($data, [ 'is_infinitescroll' => $this->is_infinitescroll, 'theme_directory' => $this->theme_directory, 'article_id' => $article_id ]) ); } else { $more_comments_to_display = false; } echo json_encode([ 'html' => $content, 'page' => $page_number, 'more_comments_to_display' => $more_comments_to_display, 'article_id' => $article_id ]); exit(); } private function get_commentQuery(int $article_id, int $limit = 0, int $offset = 0): object { $commentQuery = Comment::where(['article_id' => $article_id, 'approved' => 1]) ->orderBy('id', $this->comments_orderby_direction) ->with(['replies' => function ($query) { $query->where('approved', 1); }]); if ($offset > 0) $commentQuery = $commentQuery->offset($offset); if ($limit > 0) $commentQuery = $commentQuery->limit($limit); return $commentQuery; } } [/code] Модель комментариев: [code]class Comment extends Model { use HasFactory; protected $fillable = [ 'user_id', 'article_id', 'parent_id', 'body', 'approved' ]; // Join users to comments public function user() { return $this->belongsTo(User::class); } // Join articles to comments public function article() { return $this->belongsTo(Article::class); } // Join comment replies to comments public function replies() { return $this->hasMany(Comment::class, 'parent_id'); } } [/code] Список комментариев (и ответов) Blade: [code]@if ($comments && count($comments)) @foreach ($comments as $comment) @if (is_null($comment->parent_id)) [i]user->avatar) }}" alt="{{ $comment->user->first_name }} {{ $comment->user->last_name }}" class="rounded-circle me-1"> {{ $comment->user->first_name }} {{ $comment->user->last_name }} says: {{ date('jS M Y', strtotime($comment->created_at)) }} {{ $comment->body }} [list] @if (Auth::check() && $comment->user->id !== Auth::id()) [*] [/i] @endif @if (Auth::check() && $comment->user->id === Auth::id()) [*] [i][/i] [*] @include( 'themes/' . $theme_directory . '/partials/comment-delete-form', ['commentOrReply' => $comment] ) @endif [/list] {{-- Edit form --}} @include('themes/' . $theme_directory . '/partials/comment-edit-form', [ 'commentOrReply' => $comment, ]) {{-- Reply form --}} @if (Auth::check()) @include('themes/' . $theme_directory . '/partials/comment-form', [ 'article' => $article, 'parent_id' => $comment->id, ]) @endif {{-- Replies --}} @if ($comment->replies && count($comment->replies)) @foreach ($comment->replies as $reply) [i]user->avatar) }}" alt="{{ $reply->user->first_name }} {{ $reply->user->last_name }}" class="rounded-circle me-1"> {{ $reply->user->first_name }} {{ $reply->user->last_name }} says: {{ date('jS M Y', strtotime($reply->created_at)) }} {{ $reply->body }} [list] @if (Auth::check() && $reply->user->id === Auth::id()) [*] [/i] [*] @include( 'themes/' . $theme_directory . '/partials/comment-delete-form', ['commentOrReply' => $reply] ) @endif [/list] {{-- Edit form --}} @include( 'themes/' . $theme_directory . '/partials/comment-edit-form', ['commentOrReply' => $reply] ) @endforeach @endif @endif @endforeach @endif [/code] Проблема Когда загрузка комментариев при прокрутке страницы через AJAX [b]отключена[/b] (для этого у меня есть опция в разделе «Настройки» CMS), по причине, которую я не смог обнаружить, загружаются не все комментарии и ответы к статьям, хотя я одобрил все комментарии, относящиеся к проверенной мной статье. Я подозреваю, что ошибка находится в ArticlesController, но мне не удалось ее обнаружить. Этот шаг кажется излишним, поскольку уже существует метод get_commentQuery: [code]// Approved top-level comments with approved replies $comments = Comment::where('article_id', $article->id) ->where('approved', 1) ->whereNull('parent_id') ->with(['replies' => function ($query) { $query->where('approved', 1); }]) ->orderBy('id', 'desc') ->get(); [/code] [list] [*]В чем причина этой ошибки? [*]Каков наиболее надежный способ ее исправить? [/list] Подробнее здесь: [url]https://stackoverflow.com/questions/79788075/what-causes-the-failure-to-display-all-article-comments-in-my-laravel-8-blogging[/url]