Laravel 按日期获取以前的记录(优化)
Posted
技术标签:
【中文标题】Laravel 按日期获取以前的记录(优化)【英文标题】:Laravel Get previous records by date (optimization) 【发布时间】:2020-08-12 02:43:03 【问题描述】:我有一个带有字段的预订表:
姓名 |字符串 来自 |日期时间 到 |日期时间我选择其中一些预订并将它们显示为列表。我还会检查之前的预订是否相隔不到 30 天。
我通过查询每个预订的前一个预订来做到这一点:
@if ($booking->previousBooking()) // Simplified version but you get the idea
底层代码:
public function previousBooking()
return Booking::where('from', '<', $this->from)
->orderByDesc('from')
->first();
您可能已经猜到了:它为每个预订添加了一个查询。
最好的情况是急切地加载“以前的预订”(with),这样就可以像这样访问它:
$booking->previous_booking->from
有没有办法做到这一点?
约束:
我无法查询所有预订,按“from”排序,然后只获取上一个索引【问题讨论】:
【参考方案1】:看看 Jonathan Reinink 的 this article。您可以通过在您的 Booking 模型上模拟 previous_booking_id
来应用他的解决方案。然后添加previousBooking()
关系并使用with('previousBooking')
查询。如果您在实施方面需要任何帮助,请告诉我。
更新
将以下范围添加到您的 Booking 模型:
public function previousBooking()
return $this->belongsTo(Booking::class);
public function scopeWithPreviousBooking($query)
$query->addSelect(['previous_booking_id' => Booking::select('id')
->whereColumn('previous_booking.from', '<', 'bookings.to')
->orderByDesc('from')
->take(1)
])->with('previousBooking');
您现在可以使用以下方式获取所有包含之前预订 ID 的预订:
$bookings = Booking::withPreviousBooking()->get();
现在所有预订都应该有一个previous_booking_id
。我们将with('previousBooking')
添加到范围的末尾,就像我们查询预订的关系一样。 Eloquent 不关心 previous_booking_id
是否在数据库中,只要它在模型中可用(我们已经通过 addSelect()
方法完成)。
您现在应该可以在视图中使用您请求的解决方案了:
$booking->previousBooking->from
注意:如果您已应用范围,则只能访问previousBooking 关系。如果没有,previous_booking_id
不可用,因此关系将为空。如果您总是想加载以前的预订,请考虑将其添加为global scope。但是,我建议只在需要的地方应用范围。
【讨论】:
你将如何模拟previous_booking_id? 我已经更新了我的答案。这应该很适合你!这是我所知道的最优化的解决方案。 好吧,我已经做到了(添加了 return $this->belongsTo(Booking::class, 'previous_booking_id');)。但是现在我每次预订都得到相同的先前预订(相同的 ID)。你知道那可能是从哪里来的吗? 问题出在子查询中。 “从”是一个日期吗?你能确保记录不都是一样的吗?尝试重写子查询以确保选择正确的先前预订 是的,找到了。我需要像这样更改表名: DB::table('Bookings AS previous_booking')->select('previous_booking.id')以上是关于Laravel 按日期获取以前的记录(优化)的主要内容,如果未能解决你的问题,请参考以下文章