Вы можете использовать оператор ->>
для доступа к определенному полю JSON в виде текста:
SELECT opening_hours->>'Monday' AS monday_opening_hour FROM shops;
То же самое для closing_hours
, он просто меняет имя столбца и поля.
Таким образом, представление AR в вашем случае будет выглядеть следующим образом:
Product
.joins(:shop)
.where(
"shops.opening_hours->>:day <= :now AND shops.closing_hours->>:day >= :now",
day: day_today,
now: time_now
)
Вы можете легко связать имя ключа и время, которое вы собираетесь запрашивать, здесь как day
и now
.
Обратите внимание, что явно указывать имя таблицы не нужно, но я делаю это просто для ясности.
Это также можно сделать с помощью оператора BETWEEN:
Product
.joins(:shop)
.where(
":now BETWEEN shops.opening_hours->>:day AND shops.closing_hours->>:day",
day: day_today,
now: time_now
)
Вы можете использовать тот, который вы считаете более понятным.
В любом случае вы можете избавиться от сохранения переменной time_now
, используя функцию NOW
PostgreSQL.Он будет обрабатывать разницу формата времени, если вы приведете его к тексту (NOW()::text
):
Product
.joins(:shop)
.where(
"NOW()::text BETWEEN shops.opening_hours->>:day AND shops.closing_hours->>:day",
day: day_today
)
Аналогично, день также можно получить из NOW
.Вы можете использовать to_char(NOW(), 'Day')
для этого
SELECT to_char(date, 'Day') AS day
FROM generate_series (NOW() - '6 days'::interval, NOW(), '1 day') date;
day
-----------
Thursday
Friday
Saturday
Sunday
Monday
Tuesday
Wednesday
Итак:
Product
.joins(:shop)
.where("NOW()::text BETWEEN shops.opening_hours->>(to_char(NOW(), 'Day'))
AND shops.closing_hours->>(to_char(NOW(), 'Day'))")