查询用户的可用性



我正在建立一个网站,用户可以在此处发布可用性(例如,星期一2 pm-4pm(,并与其他用户预订聊天。

我的数据库是Postgres(Rails中的应用程序(,所以我想让数据库进行繁重的举重。

我想显示用户可用性的日历视图,因此我尝试生成一个星期的列表(时间,可用?(,以轻松渲染HTML。

让我们设置模式和数据:

$ createdb demo
$ psql demo
demo=# CREATE TABLE users (id SERIAL PRIMARY KEY, timezone VARCHAR);
demo=# CREATE TABLE timeslots (id SERIAL PRIMARY KEY, user_id INTEGER NOT NULL, days INTEGER[] NOT NULL, start_time TIME NOT NULL, end_time TIME NOT NULL);
demo=# CREATE TABLE chats (id SERIAL PRIMARY KEY, host_user_id INTEGER NOT NULL, guest_user_id INTEGER NOT NULL, start_time TIMESTAMP NOT NULL, end_time TIMESTAMP NOT NULL);
demo=# INSERT INTO users (timezone) VALUES ('America/Los_Angeles');
demo=# INSERT INTO users (timezone) VALUES ('America/New_York');
demo=# INSERT INTO timeslots (user_id, days, start_time, end_time) VALUES (1, '{3}', '10:00', '15:00');
demo=# INSERT INTO chats (host_user_id, guest_user_id, start_time, end_time) VALUES (1, 2, '2019-06-26 11:30:00', '2019-06-26 12:30:00');

现在,我想为用户生成一个可用性列表,以30分钟块的日历显示。

我提出了以下查询:(对于用户ID = 1(

WITH time_range AS (
  SELECT generate_series(
    '2019-06-26 00:00:00'::timestamp,
    '2019-06-26 23:59:59'::timestamp,
    '30 minutes'
  ) AS time
)
SELECT time, EXISTS (
  SELECT 1
  FROM timeslots
  WHERE user_id = 1
    AND extract(dow from time) = ANY(days)
    AND start_time <= time::time
    AND (time + '30 minutes'::interval)::time <= end_time
) AND NOT EXISTS (
  SELECT 1
  FROM chats
  WHERE (
    host_user_id = 1
    OR guest_user_id = 1
  ) AND start_time <= time
    AND (time + '30 minutes'::interval) <= end_time
) AS available
FROM time_range;

结果看起来有点像这样,但我无法正确获取可用性:(

        time         | available 
---------------------+-----------
 2019-06-26 00:00:00 | f
 2019-06-26 00:30:00 | f
 2019-06-26 01:00:00 | f
 2019-06-26 01:30:00 | f
...
 2019-06-26 23:30:00 | f
(48 rows)

对改进此查询或一般方法的任何帮助将不胜感激。查看彼此可用性的用户可能会有不同的时区。预订聊天的开始和结束时间存储在UTC中。在输出中将时区也很棒。

感谢您的帮助!

好了,但是我通过实际使用基于JS的日历而不是在Plain HTML中编写我的日历来解决此问题。

我决定将fullcalendar.io与TimeGrid视图一起使用-https://fullcalendar.io/docs/timegrid-view

您可以指定从服务器获取事件并正确呈现的URL:

const calendarEl = document.getElementById('calendar-schedule')
var calendar = new FullCalendar.Calendar(calendarEl, {
  eventSources: [{
    url: '/availabilities',
    eventDataTransform: (event)  => {
      return {
        id: event.id,
        start: event.starts_at,
        end: event.ends_at,
        title: 'available'
      }
    }
  }]
})

这样,您的API只需要返回用户可用的现有时间段。

如果我没记错的话,请放置

#/config/application.rb
    config.active_record.default_timezone = :utc

通过时区Aswell

使时间显示

最新更新