I've built a nested comment system and it works fine, but I have a problem. when I want to show the comments, it runs too many queries. for example if I have 10 comments and two replies each, laravel debugger shows 40 queries, and I want to reduce them, here is my code :
Query
$comments = $post->mentions()->with(['author', 'reply'])->get();
Relationship in Post.php Model
public function mentions()
{
return $this->hasMany(Comment::class, 'post_id')->where('approved',1)->where('parent_id',0);
}
Comments Relationships
public function author()
{
return $this->belongsTo(User::class, 'author_id')->select('id', 'name', 'avatar', 'role');
}
public function reply()
{
return $this->hasMany(Comment::class, 'parent_id')->where('approved', 1);
}
Blade File
@foreach ($comments as $comment)
<div x-data="{reply:false}" id="answer-{1}">
<div wire:ignore >
<div >
<img src="{{ $comment->author->avatar }}"
alt="{{ $comment->author->name }}">
<div>
<div >
<a href="/@username"
>{{ $comment->author->name }}</a>
@if ($comment->author->role == 'administrator')
<img src="/img/verified.svg" alt="" title="admin">
@endif
</div>
<p >
{{ $comment->created_at->diffForHumans() }}</p>
</div>
</div>
<svg @click="reply = true" xmlns="http://www.w3.org/2000/svg"
fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" />
</svg>
</div>
<div >
<div wire:ignore>
{!! nl2br($comment->body) !!}
</div>
<div x-cloak x-show="reply">
<form wire:submit.prevent="SubmitComment({{ $comment->id }})">
<textarea wire:model.defer="commentBody"
id="editor" rows="6" placeholder=""></textarea>
@error('commentBody') <p >{{ $message }}</p>
@enderror
<div >
<div @click="reply = false"
>
Cancel
</div>
<button wire:loading.remove wire:target="SubmitComment" type="submit"
>
Send
</button>
<button wire:loading="" wire:target="SubmitComment" type="button"
disabled>
<span >
<svg xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 24 24">
<circle cx="12" cy="12" r="10" stroke="currentColor"
stroke-width="4"></circle>
<path fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z">
</path>
</svg>
</span>
</button>
</div>
</form>
</div>
<div >
@include('partials.comment',['comments'=>$comment->reply])
</div>
</div>
</div>
@endforeach
CodePudding user response:
You can use dot seperator to get the nested relationship
$comments = $post->with(['mentions.author','mentions.reply'])
->first()
->mentions;
