我在使用此方法时遇到问题,我已阅读文档,但我要么做错了什么,要么不理解它是如何工作的,或者这是一个错误。
我的控制器中有以下代码:
$books = Book::whereDoesntHave("author", function ($query) {
$query->whereNotNull("died_at");
})->get();
现在应该做的是返回所有作者仍然活着的书籍以及所有没有作者的书籍,但它的作用恰恰相反。
我假设
whereDoesntHave()
应该检查模型是否没有指定的关系,在本例中是一个 author
模型,其中 died_at
列具有特定值。
相反,它会检查
author
模型,其中 died_at
列没有值。
我对此很困惑,这个功能到底应该如何工作?有人可以向我解释一下吗?
你可以尝试一下吗,
doesntHave("author")
检查没有作者的书籍和whereHas
关闭检查实时作者
$books = Book::doesntHave("author")->orWhereHas("author", function ($query) {
$query->whereNotNull("died_at");
})->get();
为任何可能正在寻找类似问题的更新答案的人回答这个问题。使用 Laravel 查询范围可能是最好的方法:
在您的情况下,您想要检索作者活着或没有作者的书籍。您可以使用
whereDoesntHave
模型上的自定义查询范围来实现此目的,而不是使用 Book
。以下是如何为您的场景定义查询范围的示例:
// Inside your Book model
public function scopeAliveAuthorsOrNoAuthor($query)
{
return $query->whereHas('author', function ($subquery) {
$subquery->whereNull('died_at');
})->orWhereDoesntHave('author');
}
您可以将此函数命名为任何名称,只要它以
scope
开头,以便 Laravel 将其识别为查询范围。
现在,在您的控制器中,您可以像这样使用此范围:
$books = Book::aliveAuthorsOrNoAuthor()->get();
如您所见,要在我们的构建器上应用范围,我们可以使用之前定义的范围而无需在开头使用scope一词,它将自动为我们应用过滤器。范围的更多示例是
scopeWhereAuthorIsAlive($query)
,然后将其称为 ``Book::whereAuthorIsAlive()```