有效的Postgresql查询,用于在带有Rails的简单日历上对约会进行排序

问题描述 投票:2回答:1

TL; DR:我有一个包含数千个具有start_time和end_time属性的约会的数据库。给定日期范围(5月26日至6月31日),我如何查找在此范围内发生的每项约会?

不包括从5月15日到5月25日的任命5月15日至5月29日的约会需要包括在内需要包括从6月1日到6月3日的约会需要包括从6月20日到7月5日的约会需要包括从5月15日到7月15日的约会(问题中最困难的部分)不包括从7月1日到7月4日的任命


我们有一个具有开始时间和结束时间的约会模型。如果约会在每月视图的任何一天发生,则需要将其加载到实例变量(@monthly_appointments)中,以便simple_calendar gem可以在日历上显示它。

示例:当用户查看“ 2020年6月”日历时,需要显示6月1日至6月3日的约会。从5月15日到7月15日的约会也需要在6月的每一天显示。

日历日期的两边都有6天的填充,因为如果一周从星期六(6月1日)开始,则6月日历上将显示5月26日至5月31日(见图)。

[您认为这很容易地说,“如果约会在给定月份内开始或结束,请将该约会添加到实例变量中。但是,在某些情况下,约会从5月15日开始持续60天,直到7月15日为止。约会在6月期间既不会开始也不会结束,但是它仍需要显示在日历上。

最初,我们告诉用户,“约会的持续时间不能超过6个月”,然后在假定的地方使用此查询,”如果约会在过去6个月内开始,请将其包含在变量中,然后让日历中的宝石算出其余的部分。“

@monthly_appointments = current_user.appointments.includes(:pet).where(start_time: (Time.zone.now).beginning_of_month - 6.months..(Time.zone.now).end_of_month + 6.days))

但是,此查询有时可以在变量中保存3,000多个约会,而实际上,该月只需要显示50-70个约会。

因此,我编写了以下代码,它成功地找到了在日历时间范围内至少一天发生的约会。它比较月历的范围(5月26日至6月31日)和约会的范围(6月1日至6月3日),然后查找两个数组(&)中出现的任何日期。它运作良好,但要花一点时间,因为它需要为一个用户(数千个)加载所有约会,然后逐一检查该约会是否在该月发生。

有人对此查询问题有其他聪明的解决方案吗?我确定那里有东西,但是我还没有找到。谢谢!

month_dates = ((Time.zone.now.beginning_of_month - 6.days)..(Time.zone.now.end_of_month + 6.days)).to_a

@monthly_appointments = current_user.appointments.includes(:pet).select do |appt|
  #create array of appointment dates and see if it intersects any of the monthly date array
  appt_dates = (appt.start_time.to_date..appt.end_time.to_date).to_a
  (month_dates & appt_dates).present?
end
Models:
Appointment(start_time, end_time, note, user_id, pet_id)

Pet
has_many appointments

User
has_many appointments

Here's an example.

carley = Pet.find(12)

Appointment.create(pet_id: carley.id, start_time: "May 15 2020 06:00:00", end_time: "July 15 2020 06:00:00"...)

[当我查看2020年6月的日历时,此约会需要每天显示。

enter image description here

TL; DR:我有一个包含数千个具有start_time和end_time属性的约会的数据库。给定日期范围(5月26日至6月31日),我如何查找在此整个过程中发生的每个约会...

ruby-on-rails ruby postgresql
1个回答
0
投票
from_time = '2019-05-26'.to_date
to_time = '2919-06-30'.to_date

@appointments = Appointment.where('start_time <= ? AND end_time >= ?', to_time, from_time)
© www.soinside.com 2019 - 2024. All rights reserved.