0

I don't want to add $c1, $c2, $c3, ... infinitely.

Is there a way to fix this?

public function comment() {
    $c1 = Comment::where('parent_id', $this->id)->pluck('id');
    $c2 = Comment::whereIn('parent_id', $c1)->pluck('id');
    $c3 = Comment::whereIn('parent_id', $c2)->pluck('id');
    $c4 = Comment::whereIn('parent_id', $c3)->pluck('id');
  
    $comments = Comment::query()
    ->where('parent_id', $this->id)
    ->orWhereIn('parent_id', $c1)
    ->orWhereIn('parent_id', $c2)
    ->orWhereIn('parent_id', $c3)
    ->orWhereIn('parent_id', $c4);
    
    return $comments ;
}
Noso Sanas
  • 51
  • 7
  • 3
    What are you trying to do? So that we do not misunderstand you. - And what version of php / laravel are you running? – Stoff Apr 07 '22 at 06:52
  • You can pass variables $c1,$c2.... as array. it will reduce the code – yadu siva das Apr 07 '22 at 06:55
  • 1
    Most likely comments can have comments and these comments can again have comments an unlimited amount of times. So the author wants to look up all comments in a "deep" way. – Aless55 Apr 07 '22 at 06:56
  • 1
    There are probably easier ways to get (recursive) comments – brombeer Apr 07 '22 at 06:56
  • $items = Item::whereIn('id', [1,2,..])->get(); like this – yadu siva das Apr 07 '22 at 06:57
  • Refer [Multi-tiered Comment Replies: Display and Storage](https://stackoverflow.com/a/4060252/8053274) – User863 Apr 07 '22 at 06:59
  • It looks like you're looking for a nested set: https://github.com/lazychaser/laravel-nestedset – Keith Brink Apr 07 '22 at 07:01
  • @Stoff php 7.3 and laravel 5.3 – Noso Sanas Apr 07 '22 at 07:07
  • Comment B reply to Comment A. Comment C reply to Comment B. Comment D reply to Comment C. When deleting comment A, I want comments B, C, D to be deleted. – Noso Sanas Apr 07 '22 at 07:10
  • It might be worth having a look at [Nested Sets](https://github.com/lazychaser/laravel-nestedset) for something like this. Failing that, [this post](https://stackoverflow.com/questions/20215744/how-to-create-a-mysql-hierarchical-recursive-query) may help if you're using MySQL. – Rwd Apr 07 '22 at 07:24

2 Answers2

1

You could try this

$c1 = Comment::where('parent_id', $this->id)->pluck('id');
for($i = 1;$i<=4;$i++) {
    @${'c'.$i} = Comment::whereIn('parent_id', @${'c'.$i})->pluck('id');
}

Well, the part in the query I'm not sure how to make it automatically added it. But if using DB::raw('') maybe but I'm not how much $c1,$c2,$c3,$c4,$c5 you want.

MamaWin
  • 330
  • 1
  • 2
  • 11
1

Make self relations in Comment model

Comment.php

public function parent()
{
    return $this->belongsTo(self::class, 'parent_id');
}

public function child()
{
    return $this->hasOne(self::class, 'parent_id');
}

going top to bottom in heirarchy

CommentController.php

use Illuminate\Support\Collection;
......
$parent = $this;
$ids= new Collection();

while ($parent->child) { // loop will stop if parent has no child
    $ids->push($parent->child->id);
    $parent = $parent->child; // make child as parent to continue loop to get child of child
}

$comments = Comment::whereIn('parent_id', $ids)->get()

going bottom to top in heirarchy

CommentController.php

use Illuminate\Support\Collection;
......
$child= $this;
$ids= new Collection();

while ($child->parent) { // loop will stop if parent has no child
    $ids->push($child->parent->id);
    $child= $child->parent; // make child as parent to continue loop to get child of child
}

$comments = Comment::whereIn('parent_id', $ids)->get()

If you have comment with many replies and replies of replies and you want to get top parent comment and all of his replies so you can do it like this

Comment.php

// This relation will work like loop it will get all replies with replies
//because it call ->with() function on each instance
public function replies()
{
    return $this->hasMany(self::class, 'parent_id')->with('replies);
}

CommentController.php

use App\Models\Comment;
.......
return Comment::where('parent_id', null) // This condition get top parent comment 
               ->with('replies')
               ->get()

And you can call relation on instance to get his replies

return $parentComment->replies;
  • Please help me fix this https://i.ibb.co/8gKsf80/Screenshot-14277.jpg Now it only shows comments in the green frame. How to make it show comments in the orange frame too? Because it is a child of comment 1. – Noso Sanas Apr 12 '22 at 06:44
  • 1
    First of all, I add another section to my answer at the last, take a look, may it increase your knowledge, And let me know how many levels of replies do you want? If it is limited so you can add a column named level in the comments table and can easily track the level of reply. If it has an infinity of levels so we will find a solution for that. Happy coding :-) – Abdul Haseeb Khan Apr 12 '22 at 19:36
  • Yes, it has infinite levels of replies. – Noso Sanas Apr 13 '22 at 03:38
  • 1
    https://ux.stackexchange.com/questions/1712/what-is-a-good-way-to-display-infinite-nested-comments Please also check Facebook comment modal . – Abdul Haseeb Khan Apr 13 '22 at 05:36