Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi-tiered comment system Laravel

Tags:

I'm having difficulty with blade recursive partial views. Everything works for the most part with the exception of recursion in the comment.blade.php file.

I know I need to use a foreach around the @include('articles.comments.comment', $comment) to call itself again, but I'm not sure how to call for it.

article_comments table:

id message user_id parent_id created_at updated_at 

app\Article.php Class:

class Article extends Model {      protected $table = 'articles';      protected $fillable = [         'category',         'title',         'permalink',         'synopsis',         'body',         'source',         'show_author',         'published_at'     ];      protected $dates = ['published_at'];      public function scopePublished($query)     {         $query->where('published_at', '<=', Carbon::now());     }      public function setPublishedAtAttribute($date)     {         $this->attributes['published_at'] = Carbon::parse($date);     }      public function comments()     {         return $this->hasMany('App\Comments')->where('parent_id', 0);     }  } 

app\Comments.php Class:

class Comments extends Model {      protected $table = 'article_comments';      protected $fillable = [         'parent_id',         'message',     ];      public function author() {         return $this->belongsTo('App\User');      }      public function children()     {         return $this->hasMany('App\Comments', 'parent_id');     }      public function countChildren($node = null)     {         $query = $this->children();         if (!empty($node)) {             $query = $query->where('node', $node);         }          $count = 0;         foreach ($query->get() as $child) {             // Plus 1 to count the direct child             $count += $child->countChildren() + 1;          }         return $count;     }  } 

app\Http\Controllers\ArticlesController.php:

public function show($permalink) {     $article = Article::where('permalink', '=', $permalink)->with('comments','comments.author','comments.children')->first();     if ($article != null) {         $comments = $article->comments;         return view('articles.show', compact('article','comments'));     } else {         return redirect('/')->with('error', 'This article does not exist.');     } } 

resources\views\articles\show.blade.php

@if (count($comments) > 0)     <ul>     @foreach ($comments as $comment)         @include('articles.comments.comment', ['comment'=>$comment])     @endforeach     </ul> @else     no comments @endif 

resources\views\articles\comments\comment.blade.php

<li>     {{ $comment->message }}      @if (count($comment->children) > 0)         <ul>         @foreach ($comment->children as $child)             @include('articles.comments.comment', ['comment'=>$child])         @endforeach         </ul>     @endif </li> 

Current error:

Invalid argument supplied for foreach() (View: /var/www/dev.example.com/resources/views/articles/comments/comment.blade.php) (View:  
like image 794
O P Avatar asked Jan 28 '16 22:01

O P


1 Answers

You're pretty close. I think this should work:

resources\views\articles\show.blade.php

@if (count($comments) > 0)     <ul>         @each('articles.comments.comment', $comments, 'comment');     </ul> @else     no comments @endif 

resources\views\articles\comments\comment.blade.php

<li>     {{ $comment->message }}      @if (count($comment->children) > 0)         <ul>             @each('articles.comments.comment', $comment->children, 'comment');         </ul>     @endif </li> 

app\Http\Controllers\ArticlesController.php:

$article = Article::where('permalink', '=', $permalink)->with('comments','comments.author','comments.children')->first(); $comments = $article->comments; return view('articles.show', compact('article','comments')); 
like image 134
Jeff Avatar answered Sep 30 '22 05:09

Jeff