php - Laravel 雄辩的查询使用带有条件语句和参数的本地范围
问题描述
我在我的 Car 模型中编写了以下函数,它执行以下操作:
- 根据两个日期(接送/下车)获取相关预订
- 检查这些预订的数量是否等于或超过汽车的数量
- 最后根据输出返回一个布尔值
/**
* Custom Functions
*/
public function isAvailableFor($from, $to) {
$reservationsCount = $this->reservations->where('pickup_date', '>=', $from)->where('dropoff_date', '<=', $to)->count();
if($reservationsCount >= $this->quantity) {
return false;
}
return true;
}
该功能按预期工作,但我想使用本地范围以更优雅的方式实现它,因此我可以在控制器中查询 Car 模型时有效地使用它,但我找不到正确的方法和我的代码变得一团糟。
例如,我只需键入以下范围即可使用Car::active()->get();
/**
* Scopes
*/
public function scopeActive($query)
{
return $query->where('status', 'active');
}
主要问题是该count()
功能不允许我以范围方式实现我的功能,或者至少我没有提出解决方案的经验。提前致谢。
更新
正如 OsDev 正确指出的那样,因为我的函数返回一个布尔值,所以它不能直接在作用域函数中实现。我也可以在我的作用域函数中执行此操作,但我想这有点矫枉过正:
public function scopeAvailable($query, $from, $to) {
$excludedId = array();
$cars = Car::whereHas('reservations')->get();
foreach($cars as $car) {
if(!$car->isAvailableFor($from, $to)) {
array_push($excludedId, $car->id);
}
}
return $query->whereNotIn('id', $excludedId);
}
解决方案
您必须返回$query
计数结果,因为这样您就不会破坏 Query Builder 链
您不能组合作用域和模型函数,因为作用域应该返回$query
构建器对象,在该示例中,您的函数返回一个布尔值。
你可以做这样的事情
/**
* Scopes
*/
public function scopeIsAvailableFor($query,$from,$to)
{
return $query->where('pickup_date', '>=', $from)->where('dropoff_date', '<=', $to);
}
然后你可以链接它并调用 count 如果你想
$count = Car::active()->isAvailableFor('2020-05-03','2020-05-06')->count();
也许您可以将新范围包装到模型方法中
public function isAvailableFor($from, $to) {
$reservationsCount = $this->reservations->isAvailableFor($from,$to)->count();
return !$reservationsCount >= $this->quantity;
}
推荐阅读
- python - 加入不同长度、不同键 ID 和重复项的 pandas 数据帧
- unity3d - AdMob 导致 FPS 下降?
- python - TensorFlow 没有安装?
- python - Web3.eth:溢出错误:Python int 太大而无法转换为 C ssize_t
- linux - Linux 文件命令使用哪个系统调用?
- flutter - 颤振图表处理图例新闻
- ruby-on-rails - Rails reverse proxied by Nginx: change of origin problem
- node.js - Nodejs-cron for logging
- svelte - Svelte 获取当前 svelte 文件的所有属性
- android - 流星移动应用程序不适用于 android 9 和 10