Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

voilatech's avatar

My query using nested eager loading dose not trigger the targeted data!

Hello all, I want to query some data using nested eager loading , but it appears my query only fetch the first relation! Here are my tables:

users: id

posts: post_id,user_id

commetns: comment_id, post_id,user_id

the models: User:

public function posts()

{
  return $this->hasMany('App\Post');
}

public function comments() { return $this->hasMany('App\Comment'); }

Post:

public function user() { return $this->belongsTo('App\User','user_id');

 }

public function comments()
{
    return $this->hasMany('App\Comment');
}

Commetn:

public function post() { return $this->belongsTo('App\Post', 'post_id'); }

public function user()
{
    return $this->belongsTo('App\User' ,'user_id');
}

my nested eager loading:

$post = Post::with('user.comments')->find($id);

and I get an error on commetns method!

However if I put $post= Post::with('user')->find($id);

it retrieves the post with the user who owns the post.

Now, I want to fetch above along with comments which belongsTo this specific post .

Your thoughts are greatly appreciated!

Thanks in advanced .

0 likes
14 replies
lostdreamer_nl's avatar
$posts = Post::with('comments.user')->find($id);

That will get you the post, with all it's comments, and of each comment, the user that placed it ;)

$posts = Post::with('comments.user', 'user')->find($id);

And this will get the Post, it's comments, their users, and the user that posted this post.

voilatech's avatar

@lostdreamer_nl Both throw below error :


SQLSTATE[42S22]: Column not found: 1054 Unknown column 'comments.post_id' in 'where clause' (SQL: select * from `comments` where `comments`.`post_id` in (16))

However when I put


$posts = Post::with('user.comments', 'user')->find($id);

OR


$posts = Post::with('user.comments')->find($id);

I get the post and the user without comments! Thanks

Cronix's avatar

Because your db isn't using laravel conventions.

Should be

users: id

posts: id,user_id (id, not post_id)

comments: id, post_id,user_id (id, not comment_id)
voilatech's avatar

Hi @Cronix I just updated them but still it throws the same error! not to mention if put


$post = Post::with('user.comments', 'user')->find($id);

I got what I want except comments!

when dd($post) the comments collection is empty! like so:


    #relations: array:1 [▼
        "comments" => Collection {#232 ▼
          #items: []
        }
      ]

thanks.

voilatech's avatar

@Cronix @lostdreamer_nl By doing a query like


 $posts = Post::with('comments.user', 'user')->find($id);

I get the below


local.INFO: select * from `posts` where `posts`.`id` = ? limit 1 [16] 
crnkovic's avatar

Use syntax highlighting when posting your code to the forums.

1 like
Snapey's avatar

You need a relationship between posts and comments

Post has many comments, comment belongs to Post

Therefore the comments table should have a post_id column

Otherwise, you know that the user made comments but you have no way of knowing which post they were for.

voilatech's avatar

@Snapey Already applied above! I even added foreignkey post_id in my Comment Model. not sure what is missing!? thx

voilatech's avatar

@lostdreamer_nl Now , trying to iterate through comments , to get the comments and the users who put the comment , but no luck to get the users who posted the comments in the view page .

$posts = Post::with('comments.user', 'user')->find($id);

 @foreach($posts->user as $user)

                  <td> {{$user->name}}</td>
                    @endforeach

Error

Property [user] does not exist on this collection instance.
Cronix's avatar

because the user is attached to the comment, which is attached to the post, as you said here Post::with('comments.user', 'user')

//go through all posts
foreach($posts as $post) {

    //output title (for example) of post
    echo $post->title;

    //go through all comments for this post
    foreach($post->comments as $comment) {
 
        //output comment body (for example)
        echo $comment->body;

        //output the user (author, I presume) of this comment
        echo $comment->user->name;
    }
}
Snapey's avatar

make you code clearer;

$posts = Post::with('comments.user', 'user')->find($id);

You only get one post with find, so call the variable $post

Next, if post is created by user then there is nothing to stop you calling the relationship author

public function author()
{
    return $this->belongsTo(User::class, 'user_id');
}

and then its a little clearer when you do $post->author->name

and you cannot @foreach($posts->user as $user) when the post only has one user because it is not a collection of names, just one.

Please or to participate in this conversation.