سلام دوسان من با استفاده از تابع بازگشتی کامنت های والد و فرزنهاشو نمایش دادم ولی نمایشش به دلم نیست میخام کامنت پدر اصلی همون رنگ خاکستری داشته باشه کامنت های فرزندش همشون width یه اندازه سفید رنگ رو داشته باشن و به این صورت تو در تو ظاهر نشن با استفاده از توابع بازگشتی به این شکل نمایش میده
اینم کدهاشه
@foreach ($article->comments->where('status' , \App\Comment::STATUS_ACCEPT)->where('parent_id' , null) as $comment)
<div class="comment-1">
<div class="comment-photo">
<img class="img-fluid" src="{{$comment->user->userAvatar}}" width="100%" alt="">
</div>
<div class="comment-info" style="width: 80%">
<h4 class="theme-color text-info">{{$comment->user->fullName}}</h4>
@auth
<div class="port-post-social float-right">
<a href="#mytextarea" class="replyComment" data-commentID="{{ $comment->id }}">
<i class="fa fa-reply"></i>
</a>
</div>
@endauth
<p class="badge badge-danger ml-10 mr-10">{{$comment->JalaliCreatedAT}}</p>
<p style="white-space: pre-wrap; margin-top: 10px " >{!! $comment->body !!}</p>
</div>
</div>
@include('front.comments.comment-child' , ['comment' => $comment])
@endforeach
اینم کدهای بخش تابع بازگشتی
@if (count($comment->child))
<div class="comment-1 comment-2">
@foreach ($comment->child as $child)
<div class="comment-photo">
<img class="img-fluid" src="{{$child->user->userAvatar}}" alt="">
</div>
<div class="comment-info mb-10" style="width: 80%;">
<h4 class="theme-color">{{$child->user->fullName}}</h4>
@auth
<div class="port-post-social float-right">
<a href="#mytextarea" class="replyComment" data-commentID="{{ $child->id }}">
<i class="fa fa-reply"></i>
</a>
</div>
@endauth
<p class="badge badge-danger ml-10 mr-10">{{$child->JalaliCreatedAT}}</p>
<p>{{$child->body}}</p>
</div>
@endforeach
@include('front.comments.comment-child' , ['comment' => $child])
</div>
@endif
میخام به این صورت کامنت والد و فرزندهای رو نشون بده یعنی همه فرزندها به این شکل نمایش بده که width هم اندازه داشته باشن
مشکلتون رو متوجه نشدم. خودتون کد سی اس اس رو نوشتید و برای کلاس replyComment استایلی تعریف کردید که تو رفتگی داره . خب این استایل رو تغییر بدید ظاهرتون درست میشه
یه موردی که توی کدتون هست اینه که اصلا بهینه نیست و باید روی بهینه بودن کدنون کار کنید. مشکلی که هست اینه که برای هر کامنت از طریق ریلیشن ها یه کوئری میخوره تو جدول کامنت. در صورتی که اکثر کامنت ها اصلا reply ندارن !
معمولا جداول نظرات توی هر سیستمی میتونه سنگین باشه و این برناه بعد از یه مدت میتونه بار زیادی رو به سرور و منابع فیزیکی وارد کنه.
میتونه یه راهکار این باشه که یه فیلد tinyint(1) توی جدول کامنت بزارید که مشخص میکنه این کامنت ریپلای (یا به قول شما child) داره یا نه. در صورتی که این فیلد ۱ بود فقط برای گرفتن ریپلای ها کوئری بزنید.
و هر بار که یک کامنت ریپلای ایجاد میشه شما شناسه ی کامنت اصلی رو که دارید ، این فیلد رو هم آپدیت کنید و اون رو ۱ کنید.
این یه مثال هست و اگه بازم فکر کنید روش شاید روش بهینه تری هم پیدا کنید
۲ حالت کلی برای رفع این موضوع هست
که من روش اول رو پیشنهاد میکنم. یه کوئری بنویس که از Level 1 به بعد، تمام کامنت ها رو زیر مجموعه کامنت اصلی بدونه..
به این ترتیب فایل بلید هم خیلی تر و تمیز در میاد . باید هر یک کامنت رو نشون بدی + کامنت های فرزندش رو
@behzad.azizan1991
سلام حرف شما کاملا این پروژه برا رزومه ست و کسب تجربه تو پیاده سازی و نمایش کامنت های تو در تو توی وبسایت هم هست فقط یه سوال من متوجه این قسمت از صحبتتون نشدم
مشکلی که هست اینه که برای هر کامنت از طریق ریلیشن ها یه کوئری میخوره تو جدول کامنت. در صورتی که اکثر کامنت ها اصلا reply ندارن !
مگه تو بخش نظرات وبسایت اموزشی نظرات بصورت n تعداد فرزند منطقی نیس؟
@mehrdadroshanraee69 ببینید فرض کنید سایت شما دارای 10 هزار کامنت هست.
حالا فرضا برای یک پست ، 70 کامنت ارسال شده. ازین 70 کامنت 2 کامنت دارای پاسخ هستن (منظورم کامنتی هست که در پاسخ به کامنت دیگه ای ارسال شده)
خب با کدی که شما نوشتید برای تمام 70 کامنت یک بار یک کوئری به دیتابیس میخوره که ببینه کامنت مورد نظر child داره یا نداره . 70 کوئری در جدولی با تعداد 10 هزار رکورد! در صورتی که طبق این مثالی که من زدم فقط دو کامنت دارای ریپلای هست پس اگه الگوریتمتون درست باشه به جای 70 کوئری فقط دو کوئری دریافت میشه.
@behzad.azizan1991
الان این ساختار دیتابیس منهو روابط اشتباهه؟
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('parent_id')->nullable();
$table->longText('body');
$table->enum('status' , ['accept' , 'reject' , 'pending'])->default('pending');
$table->integer('commentable_id');
$table->string('commentable_type');
$table->foreign('user_id')->references('id')->on('users')->onDelete('CASCADE');
$table->foreign('parent_id')->references('id')->on('comments')->onDelete('CASCADE');
$table->timestamps();
});
}
public function commentable()
{
return $this->morphTo();
}
public function child()
{
return $this->hasMany(Comment::class , 'parent_id');
}
@mehrdadroshanraee69 نه روابطتون درسته
فقط یک فیلد به نام has_child توی جدول comments بزارید که پیش فرض 0 هست. در صورتی که یک ریپلای برای یک کامنت ارسال شد این فیلد رو توی رکورد پدر یک کنید. با اینکار کامنت هایی که child دارن مشخص میشن . بعد به جای کد
@if (count($comment->child))
از این کد استفاده کنید :
@if($comment->has_child)
ببینید شرطی که شما گذاشتید برای هر کامنت کوئری زیر رو اجرا میکنه . یعنی به ازای هر کامنت یکبار این کوئری اجرا میشه :
select * from comments where parent_id = X
اما با اصلاحی که توی کد بدید اینکه یک کامنت childداره یا نداره از طریق یک فیلد به نام has_child مشخص میشه و نیازی به کوئری زدن دوباره توی دیتابیس نیست.
@behzad.azizan1991
دیگه با اضافه کردن این فیلد boolean نیازی به تغییرات توی ریلیشن هایی که تعریف کردم نیس؟
@mehrdadroshanraee69 نه نیازی به تغییر ریلیشن ها نیست
فقط باید موقعی که یک ریپلای برای کامنت با شناسه مثلا 2 میاد، شما باید مقدار فیلد has_child این رکورد (کامنت با آیدی 2) رو 1 کنید.
ببخشید نمونه کدی مینویسید برا این توضیحتون has_child این رکورد (کامنت با آیدی ۲) رو ۱ کنید
@behzad.azizan
public function courseComment(Course $course , Request $request)
{
$course->comments()->create([
'body' => $request->body,
'user_id' => auth()->id(),
'parent_id' =>$request->parent_id,
]);
return response()->json(['success' => 'عملیات با موفقیت انجام شد']);
}
public function courseComment(Course $course , Request $request)
{
$course->comments()->create([
'body' => $request->body,
'user_id' => auth()->id(),
'parent_id' =>$request->parent_id,
]);
Comment::where('id', $request->parent_id)
->update(['has_child' => 1]);
return response()->json(['success' => 'عملیات با موفقیت انجام شد']);
}
این کدو بزارید
آیا مایل به ارسال نوتیفیکیشن و اخبار از طرف راکت هستید ؟