راکت
مهرداد
مهرداد
توسط مهرداد مطرح شد
12 پاسخ

نمایش نظرات تو در تو در لاراول

سلام دوسان من با استفاده از تابع بازگشتی کامنت های والد و فرزنهاشو نمایش دادم ولی نمایشش به دلم نیست میخام کامنت پدر اصلی همون رنگ خاکستری داشته باشه کامنت های فرزندش همشون 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 هم اندازه داشته باشن


ثبت پرسش جدید
بهزاد عزیزان
بهزاد عزیزان
@behzad.azizan5 سال پیشمطرح شد
0

مشکلتون رو متوجه نشدم. خودتون کد سی اس اس رو نوشتید و برای کلاس replyComment استایلی تعریف کردید که تو رفتگی داره . خب این استایل رو تغییر بدید ظاهرتون درست میشه

یه موردی که توی کدتون هست اینه که اصلا بهینه نیست و باید روی بهینه بودن کدنون کار کنید. مشکلی که هست اینه که برای هر کامنت از طریق ریلیشن ها یه کوئری میخوره تو جدول کامنت. در صورتی که اکثر کامنت ها اصلا reply ندارن !
معمولا جداول نظرات توی هر سیستمی میتونه سنگین باشه و این برناه بعد از یه مدت میتونه بار زیادی رو به سرور و منابع فیزیکی وارد کنه.
میتونه یه راهکار این باشه که یه فیلد tinyint(1) توی جدول کامنت بزارید که مشخص میکنه این کامنت ریپلای (یا به قول شما child) داره یا نه. در صورتی که این فیلد ۱ بود فقط برای گرفتن ریپلای ها کوئری بزنید.
و هر بار که یک کامنت ریپلای ایجاد میشه شما شناسه ی کامنت اصلی رو که دارید ، این فیلد رو هم آپدیت کنید و اون رو ۱ کنید.
این یه مثال هست و اگه بازم فکر کنید روش شاید روش بهینه تری هم پیدا کنید


علی بیات
علی بیات
تخصص :توسعه دهنده ارشد وب
@ali.bayat5 سال پیشمطرح شد
0

۲ حالت کلی برای رفع این موضوع هست

  • تغییر کوئری
  • تغییر فایل بلید

که من روش اول رو پیشنهاد میکنم. یه کوئری بنویس که از Level 1 به بعد، تمام کامنت ها رو زیر مجموعه کامنت اصلی بدونه..
به این ترتیب فایل بلید هم خیلی تر و تمیز در میاد . باید هر یک کامنت رو نشون بدی + کامنت های فرزندش رو


مهرداد
مهرداد
@mehrdadroshanraee695 سال پیشمطرح شد
0

@behzad.azizan1991
سلام حرف شما کاملا این پروژه برا رزومه ست و کسب تجربه تو پیاده سازی و نمایش کامنت های تو در تو توی وبسایت هم هست فقط یه سوال من متوجه این قسمت از صحبتتون نشدم

مشکلی که هست اینه که برای هر کامنت از طریق ریلیشن ها یه کوئری میخوره تو جدول کامنت. در صورتی که اکثر کامنت ها اصلا reply ندارن !

مگه تو بخش نظرات وبسایت اموزشی نظرات بصورت n تعداد فرزند منطقی نیس؟


بهزاد عزیزان
بهزاد عزیزان
@behzad.azizan5 سال پیشمطرح شد
0

@mehrdadroshanraee69 ببینید فرض کنید سایت شما دارای 10 هزار کامنت هست.
حالا فرضا برای یک پست ، 70 کامنت ارسال شده. ازین 70 کامنت 2 کامنت دارای پاسخ هستن (منظورم کامنتی هست که در پاسخ به کامنت دیگه ای ارسال شده)
خب با کدی که شما نوشتید برای تمام 70 کامنت یک بار یک کوئری به دیتابیس میخوره که ببینه کامنت مورد نظر child داره یا نداره . 70 کوئری در جدولی با تعداد 10 هزار رکورد! در صورتی که طبق این مثالی که من زدم فقط دو کامنت دارای ریپلای هست پس اگه الگوریتمتون درست باشه به جای 70 کوئری فقط دو کوئری دریافت میشه.


مهرداد
مهرداد
@mehrdadroshanraee695 سال پیشمطرح شد
0

@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');
    }

بهزاد عزیزان
بهزاد عزیزان
@behzad.azizan5 سال پیشمطرح شد
0

@mehrdadroshanraee69 نه روابطتون درسته
فقط یک فیلد به نام has_child توی جدول comments بزارید که پیش فرض 0 هست. در صورتی که یک ریپلای برای یک کامنت ارسال شد این فیلد رو توی رکورد پدر یک کنید. با اینکار کامنت هایی که child دارن مشخص میشن . بعد به جای کد

@if (count($comment->child))

از این کد استفاده کنید :‌

@if($comment->has_child)

ببینید شرطی که شما گذاشتید برای هر کامنت کوئری زیر رو اجرا میکنه . یعنی به ازای هر کامنت یکبار این کوئری اجرا میشه :‌

select * from comments where parent_id = X

اما با اصلاحی که توی کد بدید اینکه یک کامنت childداره یا نداره از طریق یک فیلد به نام has_child مشخص میشه و نیازی به کوئری زدن دوباره توی دیتابیس نیست.


مهرداد
مهرداد
@mehrdadroshanraee695 سال پیشمطرح شد
0

@behzad.azizan1991
دیگه با اضافه کردن این فیلد boolean نیازی به تغییرات توی ریلیشن هایی که تعریف کردم نیس؟


بهزاد عزیزان
بهزاد عزیزان
@behzad.azizan5 سال پیشمطرح شد
0

@mehrdadroshanraee69 نه نیازی به تغییر ریلیشن ها نیست
فقط باید موقعی که یک ریپلای برای کامنت با شناسه مثلا 2 میاد، شما باید مقدار فیلد has_child این رکورد (کامنت با آیدی 2) رو 1 کنید.


مهرداد
مهرداد
@mehrdadroshanraee695 سال پیشمطرح شد
0

ببخشید نمونه کدی مینویسید برا این توضیحتون has_child این رکورد (کامنت با آیدی ۲) رو ۱ کنید
@behzad.azizan


بهزاد عزیزان
بهزاد عزیزان
@behzad.azizan5 سال پیشمطرح شد
0

@mehrdadroshanraee69 کد مربوط به ذخیره ی کامنت در دیتابیس رو بفرستید


مهرداد
مهرداد
@mehrdadroshanraee695 سال پیشمطرح شد
0

@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' => 'عملیات با موفقیت انجام شد']);
    }

بهزاد عزیزان
بهزاد عزیزان
@behzad.azizan5 سال پیشمطرح شد
0
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' => 'عملیات با موفقیت انجام شد']);
    }

این کدو بزارید


برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام