Reputation: 11188
I'm using a User/Post example in the question. I have two tables Users and Posts linked together with a many to many relationship with post_views as table. Also I've created an Event and Listener to handle the views on a post. But I only want to add a new view-entry if the last view for a given post was over an hour ago by that user.
At the moment my handle()
method in the UpdatePostViews
listener does:
public function handle(PostWasViewed $event)
{
$event->post->views()->attach($event->user->id);
}
The relationship is defined with withTimestamps
But how can I filter in the handle()
method to do something like
$lastView = User::where('user_id', $userId)
->where('post_id', $postId)
->in('post_views')
->orderBy('id', 'DESC')
->first();
which would return the last row for a user/post combination from the post_views
so I can determine on the timestamps it was inserted over an hour ago and add a new entry or skip creation of a new entry.
Upvotes: 1
Views: 1036
Reputation: 62238
You can use the wherePivot
method on the BelongsToMany
relationship to add constraints on the pivot table for the query.
Once you do that, you can use any combination of logic to determine if there was a view in the last hour. Something like:
public function handle(PostWasViewed $event)
{
$inLastHour = $event->user->posts()->where('id', $event->post->id)->wherePivot('updated_at', '>=', new \Illuminate\Database\Query\Expression('NOW() - INTERVAL 1 HOUR'))->exists();
// or, either way, shouldn't matter
$inLastHour = $event->post->views()->where('id', $event->user->id)->wherePivot('updated_at', '>=', new \Illuminate\Database\Query\Expression('NOW() - INTERVAL 1 HOUR'))->exists();
if (!$inLastHour) {
$event->post->views()->attach($event->user->id);
}
}
Upvotes: 4