Reputation: 8509
I'm having issues using this method, I have read the docs but I am either doing something wrong or not understanding how it works or it's a bug.
I have the following code in my controller:
$books = Book::whereDoesntHave("author", function ($query) {
$query->whereNotNull("died_at");
})->get();
Now what this is supposed to do is return all books whose authors are still alive and also all books that do not have an author, however it does the exact opposite.
I assumed whereDoesntHave()
is supposed to check whether the model doesn't have the specified relation, in this case an author
model with the column died_at
having a specific value.
Instead it checks the author
model where the column died_at
doesn't a value.
I'm very confused about this, how is this function supposed to work exactly? Can someone please explain this to me.
Upvotes: 2
Views: 3224
Reputation: 1118
Answering this for anyone who might be looking for an updated answer to a similar question. Using laravel query scopes could be the best approach here:
In your case, you want to retrieve books where the author is either alive or where there is no author. Instead of using whereDoesntHave
, you can achieve this using a custom query scope on your Book
model. Here's an example of how you can define a query scope for your scenario:
// Inside your Book model
public function scopeAliveAuthorsOrNoAuthor($query)
{
return $query->whereHas('author', function ($subquery) {
$subquery->whereNull('died_at');
})->orWhereDoesntHave('author');
}
you can name this function anything as long as it begins with scope
for Laravel to identify it as query scope.
Now, in your controller, you can use this scope like this:
$books = Book::aliveAuthorsOrNoAuthor()->get();
As you can see, to apply the scope on our Builder, we can use the scope defined earlier without the word scope in the beginning and it will automagically apply the filter for us. More examples for scope would be scopeWhereAuthorIsAlive($query)
and then call it as ``Book::whereAuthorIsAlive()```
Upvotes: 0
Reputation: 8287
can you try this, doesntHave("author")
check books that doesn't have author and whereHas
with closure check live author
$books = Book::doesntHave("author")->orWhereHas("author", function ($query) {
$query->whereNotNull("died_at");
})->get();
Upvotes: 1