راجہ سفیان
راجہ سفیان

Reputation: 27

I want to show posts and all of their comments in laravel

I am trying to show all posts of mine and my friends and also wanna show the comments on that posts here is my controller

$user = Auth::user();
$friend_ids = $user->friends()->pluck('friend_id')->toArray();
$posts=PostModel::whereIn('users_id',$friend_ids)
                ->orWhere('users_id',Auth::user()->id)
                ->leftJoin('users as p_user','posts.users_id','=','p_user.id')
                ->leftJoin('post_comments','posts.id','=','post_comments.post_id')
                ->leftJoin('users as c_user','post_comments.friend_id','=','c_user.id')
                -select('posts.caption','posts.image','posts.created_at','p_user.name','p_user.user_img as user_image','posts.id','c_user.user_img as commenter_img','post_comments.comment')
                ->get();

but the issue is that whenever any post have more than one comments it create more than one post and show one comment on any post , hope so you understand my question if not then I return my data here is the result

    [{"id":5,"caption":"5thpost","image":"s1.jpg","name":"roger","user_image":"roger.jpg","commenter_img":"alex.jpg","comment":"nice one"},
{"id":5,"caption":"5thpost","image":"s1.jpg","name":"alex","user_image":"alex.jpg","commenter_img":"sufi.jpg","comment":"wow"}]

here you can see the id 5 is repeating I want to show all comments of id 5

Upvotes: 1

Views: 92

Answers (2)

Ben Gooding
Ben Gooding

Reputation: 1051

You can go a step further and eager load from friends

$friends = $user->friends()->with(['posts.comments'])->get()

and you can chain on extra functions inside the with statement if required!

Likely you would want to add a between dates for the posts function for instance like:

$friends = $user->friends()->with(['posts' => function($q) use ($start, $end){
    return $q->whereBetween('created_at', [$start, $end]);
},'posts.comments'])->get()

you can get the posts with $friends->posts and the comments with $friends->posts->comments and all the data you want will already be loaded and it stops N + 1 queries!

In Friends Model:

public function posts()
{
  return $this->hasMany(Post::class);
}

In Post Model:

public function comments()
{
   return $this->hasMany(Comments::class);
}

Upvotes: 1

kmuenkel
kmuenkel

Reputation: 2789

Don't use joins, use Model Relationships. Then you can eager-load related records like:

$posts = $postModel->with('comments')->where...

The result is that each Post Model within the Collection would have a nested attribute called 'comments', the name of the method within the Model that describes the relationship. And this 'comments' attribute would contain an Eloquent\Collection of Comment Model records.

Upvotes: 1

Related Questions