我怎样在这个Laravel应用中只显示已批准的评论回复?

huangapple go评论63阅读模式
英文:

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-&gt;get_commentQuery( $article-&gt;id );
    $comments_count = $commentsQuery-&gt;count();

    // If infinite scroll, paginate comments (to be loaded one page per scroll),
    // Else show them all 

    if (boolval($this-&gt;is_infinitescroll)) {
        $comments = $commentsQuery-&gt;paginate($this-&gt;comments_per_page);
    } else {
        $comments = $commentsQuery-&gt;get();
    }

    return view( &#39;themes/&#39; . $this-&gt;theme_directory . &#39;/templates/single&#39;, array_merge(
        $this-&gt;data,
        [
            &#39;categories&#39;        =&gt; $this-&gt;article_categories,
            &#39;article&#39;           =&gt; $article,
            &#39;old_article&#39;       =&gt; $old_article,
            &#39;new_article&#39;       =&gt; $new_article,
            &#39;comments&#39;          =&gt; $comments,
            &#39;comments_count&#39;    =&gt; $comments_count,
            &#39;comments_per_page&#39; =&gt; $this-&gt;comments_per_page,
            &#39;tagline&#39;           =&gt; $article-&gt;title,
            &#39;is_infinitescroll&#39; =&gt; $this-&gt;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( [ &#39;article_id&#39; =&gt; $article_id, &#39;approved&#39; =&gt; 1 ] )
-&gt;orderBy( &#39;id&#39;, $this-&gt;comments_orderby_direction );
if ( $offset &gt; 0 ) {
$commentQuery = $commentQuery-&gt;offset( $offset );
}
if ( $limit &gt; 0 ) {
$commentQuery = $commentQuery-&gt;limit( $limit );
}
return $commentQuery;
}  

In the blade file that displays the comments - comments-list.blade.php:fv

@foreach ($comments as $comment)
    @if (null == $comment-&gt;parent_id)
        &lt;li class=&quot;depth-1 comment&quot;&gt;
            &lt;div class=&quot;comment__avatar&quot;&gt;
                &lt;img class=&quot;avatar&quot; src=&quot;{{ asset(&#39;images/avatars/&#39; . $comment-&gt;user-&gt;avatar) }}&quot; alt=&quot;{{ $comment-&gt;user-&gt;first_name }} {{ $comment-&gt;user-&gt;last_name }}&quot; width=&quot;50&quot; height=&quot;50&quot;&gt;
            &lt;/div&gt;
            &lt;div class=&quot;comment__content&quot;&gt;
                &lt;div class=&quot;comment__info&quot;&gt;
                    &lt;div class=&quot;comment__author&quot;&gt;{{ $comment-&gt;user-&gt;first_name }} {{ $comment-&gt;user-&gt;last_name }}&lt;/div&gt;
                    &lt;div class=&quot;comment__meta&quot;&gt;
                        &lt;div class=&quot;comment__time&quot;&gt;{{ date(&#39;jS M Y&#39;, strtotime($comment-&gt;created_at)) }}&lt;/div&gt;
                        @auth
                            &lt;div class=&quot;comment__reply&quot;&gt;
                                &lt;a class=&quot;comment-reply-link&quot; href=&quot;#0&quot;&gt;Reply&lt;/a&gt;
                            &lt;/div&gt;
                        @endauth
                    &lt;/div&gt;
                &lt;/div&gt;
                &lt;div class=&quot;comment__text&quot;&gt;
                    &lt;p&gt;{{ $comment-&gt;body }}&lt;/p&gt;
                &lt;/div&gt;
            &lt;/div&gt;
            @auth
                @include(&#39;themes/&#39; . $theme_directory . &#39;/partials/comment-form&#39;)
            @endauth
    
            {{-- Comment replies --}}
            @if (count($comment-&gt;replies))
                &lt;ul class=&quot;children&quot;&gt;
                    @foreach ($comment-&gt;replies as $reply)
                        &lt;li class=&quot;depth-2 comment&quot;&gt;
                            &lt;div class=&quot;comment__avatar&quot;&gt;
                                &lt;img class=&quot;avatar&quot; src=&quot;{{ asset(&#39;images/avatars/&#39; . $reply-&gt;user-&gt;avatar) }}&quot; alt=&quot;{{ $comment-&gt;user-&gt;first_name }} {{ $comment-&gt;user-&gt;last_name }}&quot; width=&quot;50&quot; height=&quot;50&quot;&gt;
                            &lt;/div&gt;
                            &lt;div class=&quot;comment__content&quot;&gt;
                                &lt;div class=&quot;comment__info&quot;&gt;
                                    &lt;div class=&quot;comment__author&quot;&gt;{{ $reply-&gt;user-&gt;first_name }} {{ $reply-&gt;user-&gt;last_name }}&lt;/div&gt;
                                    &lt;div class=&quot;comment__meta&quot;&gt;
                                        &lt;div class=&quot;comment__time&quot;&gt;{{ date(&#39;jS M Y&#39;, strtotime($reply-&gt;created_at)) }}&lt;/div&gt;
                                    &lt;/div&gt;
                                &lt;/div&gt;
                                &lt;div class=&quot;comment__text&quot;&gt;
                                    &lt;p&gt;{{ $reply-&gt;body }}&lt;/p&gt;
                                &lt;/div&gt;
                            &lt;/div&gt;
                        &lt;/li&gt;
                    @endforeach
                &lt;/ul&gt;
            @endif
        &lt;/li&gt;
    @endif
@endforeach

As the line $commentQuery = Comment::where( [ &#39;article_id&#39; =&gt; $article_id, &#39;approved&#39; =&gt; 1 ] )-&gt;orderBy( &#39;id&#39;, $this-&gt;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

  1. $comment->replies 默认会获取所有记录,没有条件限制。您需要添加条件来解决这个问题。

  2. 您可以通过在关系中添加条件来过滤已批准的评论:

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 查询问题。

英文:
  1. $comment-&gt;replies relationship by default fetching all records with no conditions. You need to add where condition to solve this.

  2. 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( [ &#39;article_id&#39; =&gt; $article_id, &#39;approved&#39; =&gt; 1 ] )
-&gt;orderBy( &#39;id&#39;, $this-&gt;comments_orderby_direction )
-&gt;with(&#39;replies&#39;, function($query){
$query-&gt;where(&#39;approved&#39;, 1);
});
if ( $offset &gt; 0 ) {
$commentQuery = $commentQuery-&gt;offset( $offset );
}
if ( $limit &gt; 0 ) {
$commentQuery = $commentQuery-&gt;limit( $limit );
}
return $commentQuery;
} 

Above query also should be solve your N+1 query problem when fetching $comment-&gt;replies in the blade file

huangapple
  • 本文由 发表于 2023年6月12日 04:03:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/76452316.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定