Active Record - select с SQL возвращает строку вместо исходного класса - PullRequest
0 голосов
/ 14 сентября 2018

У меня есть база пользователей и назначений. Встречи имеют start_time и end_time в формате TimeWithZone. Я хочу определить, какие пользователи превысили определенную общую продолжительность. К сожалению, таблица встреч не имеет встроенной длительности, поэтому мне приходится вычислять ее самостоятельно.

Если я вычитаю start_time из end_time, он возвращает float, что идеально для меня.

Appointment.first.end_date - Appointment.first.start_time
=> 3600.0
(Appointment.first.end_date - Appointment.first.start_time).class
=> Float

Если я запускаю его на всей своей таблице и пытаюсь создать новый столбец, он возвращает строку:

Appointment.select("end_time - start_time as duration").first.duration
=> "01:00:00"
Appointment.select("end_time - start_time as duration").first.duration.class
=> String

Я не уверен, почему тип изменился и как привести его обратно к float, или к какому-либо классу, с которым легче иметь дело. В идеале мой конечный запрос должен выглядеть примерно так:

User.joins(:appointments).select("users.id", "end_time - start_time as duration").group("users.id").having("SUM(duration) >= ?", timelimit) с timelimit в зависимости от максимальной продолжительности и любых единиц, которые я получу

1) Почему я получаю разные результаты для очень похожих команд

2) Как создать новый столбец, который будет содержать информацию о продолжительности каждой встречи в зависимости от времени их окончания и начала?

1 Ответ

0 голосов
/ 14 сентября 2018

Вы получаете разные результаты, потому что один выполняется Ruby, а другой - SQL.Нет причин, по которым оба должны делать одно и то же.

Вы можете использовать TIME_TO_SEC, если вы используете MySQL https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_time-to-sec

Appointment.select("TIME_TO_SEC(end_time - start_time) as duration")

TIME_TO_SEC преобразует строку "01:00:00в секундах.

mysql> SELECT TIME_TO_SEC("01:00:00");
+-------------------------+
| TIME_TO_SEC("01:00:00") |
+-------------------------+
|                    3600 |
+-------------------------+
1 row in set (0,05 sec)
...