我正在建立一个网站,用户可以在该网站上发布可用性(例如,周一和周二下午2点至下午4点),并与其他用户预订聊天记录。
我的数据库是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中。在输出中包含时区也是很好的选择。
感谢您的帮助!
答案 0 :(得分:1)
好一阵子了,但是我通过使用基于JS的日历而不是用纯HTML编写自己的日历来解决了这个问题。
我决定将Fullcalendar.io与TimeGrid视图结合使用-https://fullcalendar.io/docs/timegrid-view
您可以指定一个URL,以从服务器中获取事件并正确呈现它们:
i can arrange appointment with technical
这样,您的API仅需要返回标记为用户可用的现有时隙。
答案 1 :(得分:-1)
如果我没记错的话,放
#/config/application.rb
config.active_record.default_timezone = :utc
同时显示时区和时间