19

I have the following eloquent models:

User | id

Post | id

Comment | id | post_id | user_id

Using eloquent, how can I fetch all Posts which a specific User hasn't commented yet?

I tried so far:

In Model Post:

public function noCommentOf(User $user) {
    $this->hasNot('App\Comment')->commentOf($user);
}

In Model Comment:

public function commentOf($query, User $user) {
    return $query->where('user_id', '=', $user->id);
}
3
  • not that hard question, a bit complex but not difficult. What have you done till now to solve this problem? Commented Sep 25, 2017 at 19:57
  • Hi! I added some short code snippets how I tried it so far.
    – Frooplet
    Commented Sep 25, 2017 at 20:06
  • ok, I will have a look, will be back in some minutes Commented Sep 25, 2017 at 20:10

3 Answers 3

31

The way I would do this is by querying the Post model with a whereDoesnthave relationship. In your controller:

public function getPostsWithoutCommenter(){
  $userId = 1; // Could be `$user`, `use($user)` and `$user->id`.
  $posts = \App\Post::whereDoesntHave("comments", function($subQuery) use($userId){
    $subQuery->where("user_id", "=", $userId);
  })->get();
}

This would assume that comments is defined on the Post model as:

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

Basically, if the comments relationship with the check for that $userId returns a Collection, it would be ignored from the result set.

1
  • Thank you, very nice solution! :)
    – Frooplet
    Commented Sep 26, 2017 at 6:36
11

Post model

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

Then get posts

$posts = Post:: whereDoesntHave('comments', function ($query) use ($userId) {
    $query->where('user_id', $userId);
});

To get posts with no comments

$posts = Post::has('comments', '=', 0)->get();
2
  • how about posts with no comments? Commented Sep 25, 2017 at 20:22
  • @AndriyLozynskiy Updated my answer. Commented Sep 25, 2017 at 20:31
-1

I think:

$user->post()->leftJoin('comments', 'posts.id', '=', 'comments.post_id')->whereNull('comments.id');

Not the answer you're looking for? Browse other questions tagged or ask your own question.