Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel belongsToMany where doesn't have one of

I have two tables: categories and videos, I then have a pivot table for these as it's a belongsToMany relationship.

What I'm trying to do is get all of the videos where there isn't a single instance of the video being in one of many categories.

e.g.

  • Video 1 is in category 1, 2 and 3.
  • Video 2 is in category 1 and 3.
  • Video 3 is in category 1.

I want to get the video which is NOT in category 2 or 3, meaning this will return Video 3.

What I've tried so far, which doesn't give the intended result, this is because another row is still found for Video 1 and 2, as they are in Category 1:

Video::whereHas('categories', function($query) {
    $query->whereNotIn('category_id', [2,3]);
})->take(25)->get();

The query populated from this is:

select * from `videos` where exists (select * from `categories` inner join 
`category_video` on `categories`.`id` = `category_video`.`category_id` where 
`videos`.`id` = `category_video`.`video_id` and `category_id` != ? and 
`category_id` != ? and `categories`.`deleted_at` is null) and `videos`.`deleted_at` 
is null order by `created_at` desc limit 25
like image 585
Karl Avatar asked May 06 '17 14:05

Karl


People also ask

Does laravel 8 have one relation?

hasOne relationship in laravel is used to create the relation between two tables. hasOne means create the relation one to one. For example if a article has comments and we wanted to get one comment with the article details then we can use hasOne relationship or a user can have a profile table.

How do you make a one to one relationship in laravel?

How to define One to One relationship in Laravel? Details table migration would look like following (add columns shown below): add title, description columns. define foregin key constraint in details table because it refers to post table.

What is the difference between laravel find and where?

find returns an object instance of the model while where which uses the get method returns a collection. find returns null if no row has been returned while where which uses the get method always returns a collection which can be empty when no results have been returned from the database.


1 Answers

You can use Eloquent's whereDoesntHave() constraint to get what you need:

// get all Videos that don't belong to category 2 and 3
Video::whereDoesntHave('categories', function($query) {
  $query->whereIn('id', [2, 3]);
})->get();
like image 191
jedrzej.kurylo Avatar answered Sep 25 '22 23:09

jedrzej.kurylo