英文:
How do I display only approved comment replies in this Laravel app?
问题
在我的应用程序中,我正在处理显示评论回复的问题。
在控制器中,我像这样添加评论:
public function show($slug)
{
// 评论
$commentsQuery = $this->get_commentQuery($article->id);
$comments_count = $commentsQuery->count();
// 如果使用无限滚动,分页评论(每次滚动加载一页)
// 否则显示所有评论
if (boolval($this->is_infinitescroll)) {
$comments = $commentsQuery->paginate($this->comments_per_page);
} else {
$comments = $commentsQuery->get();
}
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' => $this->is_infinitescroll
]
));
}
/**
* get_commentQuery
*
* @param int $article_id
* @param int $limit
* @param int $offset
*
* @return object
*/
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);
if ($offset > 0) {
$commentQuery = $commentQuery->offset($offset);
}
if ($limit > 0) {
$commentQuery = $commentQuery->limit($limit);
}
return $commentQuery;
}
在显示评论的Blade文件 comments-list.blade.php
中:
@foreach ($comments as $comment)
@if (null == $comment->parent_id)
<li class="depth-1 comment">
<div class="comment__avatar">
<img class="avatar" src="{{ asset('images/avatars/' . $comment->user->avatar) }}" alt="{{ $comment->user->first_name }} {{ $comment->user->last_name }}" width="50" height="50">
</div>
<div class="comment__content">
<div class="comment__info">
<div class="comment__author">{{ $comment->user->first_name }} {{ $comment->user->last_name }}</div>
<div class="comment__meta">
<div class="comment__time">{{ date('jS M Y', strtotime($comment->created_at)) }}</div>
@auth
<div class="comment__reply">
<a class="comment-reply-link" href="#0">Reply</a>
</div>
@endauth
</div>
</div>
<div class="comment__text">
<p>{{ $comment->body }}</p>
</div>
</div>
@auth
@include('themes/' . $theme_directory . '/partials/comment-form')
@endauth
{{-- 评论回复 --}}
@if (count($comment->replies))
<ul class="children">
@foreach ($comment->replies as $reply)
<li class="depth-2 comment">
<div class="comment__avatar">
<img class="avatar" src="{{ asset('images/avatars/' . $reply->user->avatar) }}" alt="{{ $comment->user->first_name }} {{ $comment->user->last_name }}" width="50" height="50">
</div>
<div class="comment__content">
<div class="comment__info">
<div class="comment__author">{{ $reply->user->first_name }} {{ $reply->user->last_name }}</div>
<div class="comment__meta">
<div class="comment__time">{{ date('jS M Y', strtotime($reply->created_at)) }}</div>
</div>
</div>
<div class="comment__text">
<p>{{ $reply->body }}</p>
</div>
</div>
</li>
@endforeach
</ul>
@endif
</li>
@endif
@endforeach
正如 $commentQuery = Comment::where(['article_id' => $article_id, 'approved' => 1])->orderBy('id', $this->comments_orderby_direction)
这一行所示,所有评论只应在经过批准的情况下显示。这适用于“父”评论,但不适用于评论回复。您可以如何将此条件应用于回复评论?
英文:
I am working on displaying comment replies in my application.
In the controller, I add comments like this:
public function show( $slug )
{
// Comments
$commentsQuery = $this->get_commentQuery( $article->id );
$comments_count = $commentsQuery->count();
// If infinite scroll, paginate comments (to be loaded one page per scroll),
// Else show them all
if (boolval($this->is_infinitescroll)) {
$comments = $commentsQuery->paginate($this->comments_per_page);
} else {
$comments = $commentsQuery->get();
}
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' => $this->is_infinitescroll
]
));
}
/**
* get_commentQuery
*
* @param int $article_id
* @param int $limit
* @param int $offset
*
* @return object
*/
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 );
if ( $offset > 0 ) {
$commentQuery = $commentQuery->offset( $offset );
}
if ( $limit > 0 ) {
$commentQuery = $commentQuery->limit( $limit );
}
return $commentQuery;
}
In the blade file that displays the comments - comments-list.blade.php
:fv
@foreach ($comments as $comment)
@if (null == $comment->parent_id)
<li class="depth-1 comment">
<div class="comment__avatar">
<img class="avatar" src="{{ asset('images/avatars/' . $comment->user->avatar) }}" alt="{{ $comment->user->first_name }} {{ $comment->user->last_name }}" width="50" height="50">
</div>
<div class="comment__content">
<div class="comment__info">
<div class="comment__author">{{ $comment->user->first_name }} {{ $comment->user->last_name }}</div>
<div class="comment__meta">
<div class="comment__time">{{ date('jS M Y', strtotime($comment->created_at)) }}</div>
@auth
<div class="comment__reply">
<a class="comment-reply-link" href="#0">Reply</a>
</div>
@endauth
</div>
</div>
<div class="comment__text">
<p>{{ $comment->body }}</p>
</div>
</div>
@auth
@include('themes/' . $theme_directory . '/partials/comment-form')
@endauth
{{-- Comment replies --}}
@if (count($comment->replies))
<ul class="children">
@foreach ($comment->replies as $reply)
<li class="depth-2 comment">
<div class="comment__avatar">
<img class="avatar" src="{{ asset('images/avatars/' . $reply->user->avatar) }}" alt="{{ $comment->user->first_name }} {{ $comment->user->last_name }}" width="50" height="50">
</div>
<div class="comment__content">
<div class="comment__info">
<div class="comment__author">{{ $reply->user->first_name }} {{ $reply->user->last_name }}</div>
<div class="comment__meta">
<div class="comment__time">{{ date('jS M Y', strtotime($reply->created_at)) }}</div>
</div>
</div>
<div class="comment__text">
<p>{{ $reply->body }}</p>
</div>
</div>
</li>
@endforeach
</ul>
@endif
</li>
@endif
@endforeach
As the line $commentQuery = Comment::where( [ 'article_id' => $article_id, 'approved' => 1 ] )->orderBy( 'id', $this->comments_orderby_direction )
shows, all comments should be displayd only if aproved.
This does happen for the "parent" comments, but not for comment replies. How can I apply this condition to the replies?
答案1
得分: 1
-
$comment->replies
默认会获取所有记录,没有条件限制。您需要添加条件来解决这个问题。 -
您可以通过在关系中添加条件来过滤已批准的评论:
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;
}
上面的查询还可以解决在 Blade 文件中获取 $comment->replies
时的 N+1 查询问题。
英文:
-
$comment->replies
relationship by default fetching all records with no conditions. You need to add where condition to solve this. -
You can filter the approved comment by adding the condition the relationship :
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;
}
Above query also should be solve your N+1 query problem when fetching $comment->replies
in the blade file
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论