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

michiel's avatar

Eloquent: selecting only the news that hasn't been seen by current user

Hi guys,

I'm stuck on how to implement the following scenario in Eloquent:

Imagine a site that has news and logged in users that has a page where all the news item that haven't been seen by the current user need to be displayed.

For this I have made 3 database tables:

  1. users id#username#password etc.

  2. news id#title#content

  3. news_users id#news_id#user_id

In the News-model I've set the following relationship:

public function viewers()
{
    return $this->belongsToMany('User', 'news_users', 'news_id', 'user_id');
}

Now the idea is that I add a record in news_users, whenever a user marks a news item as seen.

The question now is, how to retrieve all news items that haven't been seen by the current user.

Any suggestions?

0 likes
5 replies
mstnorris's avatar

@joshbrw I had search the documentation as there was mention about a year ago of a notHas method (not particularly readable or grammatically correct). But doesntHave() is what I was after. Thanks. I'm sure @michiel will be happy with that.

michiel's avatar

Thanks @joshbrw! I indeed wasn't aware of the doesntHave method. But it does solve my issue.

In case other users might be with a similar issue, below the full Eloquent query to select all news messages that $userId hasn't seen yet:

$this->model->whereDoesntHave('viewers', function($q) use ($userId) {
    $q->where('user_id', $userId);
})->get();
joshbrw's avatar

@mstnorris Yeah.. I knew I'd seen has() when browsing and thought I'd look at the API docs as I knew Laravel would have a nicely-named negative function. :)

Please or to participate in this conversation.