Запросить доступность пользователя в Postgres - PullRequest
1 голос
/ 27 июня 2019

Я создаю веб-сайт, на котором пользователи могут публиковать информацию о доступности (например, в понедельник и вторник в 14:00 - 16:00) и забронировать чат с другим пользователем, если он доступен.

Моя база данных - 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-минутными блоками.

Я получил следующий запрос: (для идентификатора пользователя = 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. Также было бы здоровоесть часовой пояс на выходе.

Спасибо за помощь!

1 Ответ

0 голосов
/ 27 июня 2019

Если я не ошибаюсь, ставим

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

отображает время с указанием часового пояса

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...