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

codemode's avatar

User - Post - Likes to a post by user

Hello, I have 3 models - User, Post and PostLike . So, a User can create many posts, and each post can be liked by users. I', trying to get a user to like a particular post, and the be able to display all the users who have liked a particular post.

User Model :

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

Post Model :

  public function user()
    {
        return $this->belongsTo(User::class);
    }
    
    public function post_like()
    {
        return $this->hasMany(PostLike::class);
    }

PostLike Model :

    public function post()
    {
        $this->belongsTo(Post::class);
    }
    
    public function user()
    {
        $this->belongsTo(User::class);
    }

The Post Controller, where i display a list of all my posts :

public function index()
    {
        $all_posts = Post::all();

        return view('wall', compact('all_posts'));
    }

Now, i try to display the posts, it's likes, and the users who have liked it :

@if(count($all_posts))
                    @foreach($all_posts as $post)
                    <div>
                        <ul>{{ $post->body }} - by {{ $post->user->name }} | Likes = {{ count($post->post_like) }}  
| Liked by = {{ $post->post_like->user->name}} // This is throwing errors
                            <form action="/like-post" method="POST">
                                {{ csrf_field() }}
                                <input type="hidden" name="likeThePost" value={{ $post->id or ''  }} />
                                <button class="btn btn-primary" type="submit" value="Submit">Like</button>
                            </form>
                        </ul>
                    </div>
                    @endforeach
                    @endif
                </div>

Please check my comment "This is throwing errors" above. I'd appreciate if someone can point me to the right direction.

Thanks.

0 likes
6 replies
skliche's avatar

You defined

public function post_like()
    {
        return $this->hasMany(PostLike::class);
    }

So a post can have many likes.

Then you use

$post->post_like->user->name

Let's examine the first part

$post->post_like->user

What user could this refer to? A post can have many likes so post_like returns a collection. You are trying to get the property user of a collection, not a single model instance.

Do a

dump($post->post_like);

at that point and you should see what I mean.

Edit: When you understand what's going wrong here and have fixed it, have a look at nested eager loading. But don't worry about it until you fully understand what's wrong right now.

1 like
codemode's avatar

@skliche Thank you for pointing this out.

the dump($post->post_like); dumps an array which does contain the user_id.

I'm not sure how do i get the user's names from here :(

If i do $all_posts = Post::with('post_like')->with('user')->get(); - Then on doing a dd(), i see the the user's information.. Could you tell me how can i access it?

(And just to confirm, doing the Post::with('post_like')->with('user')->get(); instead of Post::with('user')->get(); will give me the users who have LIKED the post, right?)

Thanks!

skliche's avatar
skliche
Best Answer
Level 42
dump($post->post_like);

should return a collection of PostLike instances, even if it just contains a single model. You need to iterate over that collection to get each PostLike's user.

@foreach($all_posts as $post)
    {{ $post->body }} - by {{ $post->user->name }} | Likes = {{ count($post->post_like) }}
    @foreach($post->post_like as $like)
        | Liked by {{ $like->user->name }}
    @endforeach
@endforeach

Regarding the nested eager loading:

Post::with(['user', 'post_like.user'])

retrieves the posts including the post's users and the post's likes including the users who liked the post.

Seriously, don't worry about this until you get the other stuff sorted out even though it is important :-)

codemode's avatar

Hi @skliche ,

You're right, the view had to iterate through all the likes. This is what i've done now :

@if(count($all_posts))
                    @foreach($all_posts as $post)
                    <div>
                        <ul>{{ $post->body }} - by {{ $post->user->name }} | Likes = {{ count($post->post_like) }}
                         <ul> | Liked by = @foreach($post->post_like as $likes)
                                        <li>{{ $likes->user->name }}</li>
                                        @endforeach
                          </ul>
                        </ul>
                    </div>
                    @endforeach
                    
                    @endif 

In my controller if i just do this :

$all_posts = Post::all();
return view('wall', compact('all_posts'));

Then i see an error : App\PostLike::user must return a relationship instance.

What do you think? Thanks!

codemode's avatar

AH got it, in my PostLike model, i was not returning the relationship... all i had to do was to return it.. It works now!!

Also, i just tried with Post::with(['user', 'post_like.user']) ... and that works too! :)

Thanks!

1 like

Please or to participate in this conversation.