php - Laravel 使用查询构建器从日期范围创建行
问题描述
我有一个Event模型,它有EventDates
EventDate有一个from和to字段。在我的仪表板中,如果一个事件跨越多天,我需要使用查询构建器为该事件存在的每一天显示一行,以便我们可以对结果集进行分页和限制。
事件.php
public function dates()
{
return $this->hasMany(EventDate::class);
}
这就是数据在 EventDate 中的存储方式
+----+------------+------------+
| id | from | to |
+----+------------+------------+
| 1 | 09-20-2019 | 09-25-2019 |
+----+------------+------------+
这就是我希望接收数据的方式
+----+------------+
| id | date |
+----+------------+
| 1 | 09-20-2019 |
| 1 | 09-21-2019 |
| 1 | 09-22-2019 |
| 1 | 09-23-2019 |
| 1 | 09-24-2019 |
| 1 | 09-25-2019 |
+----+------------+
从集合中检索的方法
我可以使用此方法从集合中构建结果,但是这已经是结果的派生者,因此我无法对此进行分页或限制。
事件日期.php
public function getRecurringAttribute()
{
$dates = collect();
$this->upcoming()->get()->map(function ($upcomingDate) use ($dates) {
$period = CarbonPeriod::create($upcomingDate->date_from, $upcomingDate->date_until);
if (!$period->count()) {
return $upcomingDate;
}
foreach ($period as $date) {
$upcomingDate->date_from = $date;
$upcomingDate->date_until = $date;
$dates->push($upcomingDate);
}
return true;
});
return $dates;
}
所以我想知道,是否有可能使用查询生成器来实现这个结果?所以我可以对生成的结果集进行分页、限制和使用范围。
解决方案
我使用以下库 https://github.com/staudenmeir/laravel-cte/找到了解决方案。该库允许使用查询生成器或模型编写 CTE 函数。
public function scopeRecurringDates($query)
{
return $query->from('t')
->withRecursiveExpression('t', "
SELECT id, event_id, date_from as date_from, date_from as date_until, date_until as du, time_from, time_until FROM event_dates
UNION ALL
SELECT id, event_id, DATE_ADD(t.date_from, INTERVAL 1 DAY), DATE_ADD(t.date_from, INTERVAL 1 DAY), du, time_from, time_until
FROM t WHERE DATE_ADD(date_from, INTERVAL 1 DAY) <= du
");
}
在我的控制器中,我使用
$query = EventDate::recurringDates()
推荐阅读
- ruby-on-rails - 向 API::V1 模块控制器提交请求时无法验证 Railsauthentity_token
- jquery - 有按钮输入,需要让它下载已知的url
- javascript - 如何在 TypeScript 类中扩展 ES6 类
- ios - 无限水平滚轮最干净的方法是什么
- http - 在 go 中检测失败的 http 连接
- arrays - 输入新值时复制表的最后一行
- javascript - 用木偶戏刮亚马逊
- google-sheets - 有没有办法从导入范围中过滤特定数据进行平均?
- javascript - 从数组中选择正确值并分配给变量的问题
- java - 使用电子邮件和密码登录。获取 NullPointerException