我在我的一个模型中将数据库查询设置为范围查询,在某些情况下可能不会返回任何结果,这样做完全没问题:
public function scopeLastFromLaunchSite($query, $site) {
return $query->whereComplete()->whereHas('launchSite', function($q) use($site) {
$q->where('name',$site);
})->orderBy('launch_order_id','DESC')->first();
}
这个函数简单地通过以下方式调用:
Mission::LastFromLaunchSite('someSite');
如果结果中至少有一行,此查询完全可以工作,但一旦没有,它就会返回一个非常冗长的 Builder 对象,该对象充满了递归,这实际上使我的崩溃浏览器。
我的问题是...
我如何才能检测到这一点并简单地返回类似 false
或 “No results were found.”的内容。
?
我试过的...
我已经尝试使用 firstOrFail()
方法代替 first()
,但这只会返回一个 ModelNotFoundException
,这给了我两种解决方案:
在
global.php
中用App:error
处理它。这是不可取的,因为没有返回结果不是错误。只是众多可能结果中的一种。捕获每个方法中的异常,这会导致代码重复。我实际上也无法让它工作。我尝试
使用
ModelNotFoundException
类并捕获它,但它从未被捕获:use Illuminate\Database\Eloquent\ModelNotFoundException; // ... try { //my query } catch (Illuminate\Database\Eloquent\ModelNotFoundException $e) { return false; } // otherwise, return as normal
当对我的模型的查询未返回任何结果时,我如何简单地返回 false
或一些错误的值,而不是简单地打印出这个非常冗长的错误?
最佳答案
这里的问题是您没有像 Laravel 预期的那样使用作用域。 Laravel 实际上并不期望您实际在范围内执行查询。它更像是一个应用过滤器的工具。因此,当您的范围函数返回 NULL
(或任何虚假值)时,Laravel 无论如何都会返回当前的 Builder 对象:
Illuminate\Database\Eloquent\Builder
protected function callScope($scope, $parameters)
{
array_unshift($parameters, $this);
return call_user_func_array(array($this->model, $scope), $parameters) ?: $this;
}
这里有三种解决方案:
1。使用异常(但在你的 Controller 中)
我不太喜欢这样,但这是一种可能性。使用 firstOrFail
并在您的 Controller 中执行此操作:
try {
$result = Mission::LastFromLaunchSite('someSite');
} catch (Illuminate\Database\Eloquent\ModelNotFoundException $e){
$result = null;
}
2。正确使用范围
不要在范围内执行查询,而是在您的 Controller 中执行:
public function scopeLastFromLaunchSite($query, $site) {
return $query->whereComplete()->whereHas('launchSite', function($q) use($site) {
$q->where('name',$site);
})->orderBy('launch_order_id','DESC');
}
用法:
Mission::LastFromLaunchSite('someSite')->first();
3。只需向您的模型添加一个正常功能即可
public static function LastFromLaunchSite($site){
return $query->whereComplete()->whereHas('launchSite', function($q) use($site) {
$q->where('name',$site);
})->orderBy('launch_order_id','DESC')->first();
}
用法:
Mission::LastFromLaunchSite('someSite');
关于php - 如何强制 Laravel Eloquent 很好地处理不返回任何结果的查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28122576/