У меня есть приложение для отслеживания температуры в связи с глобальным потеплением.
У меня есть база данных PG, записывающая температуры, а затем пытающаяся сравнить записи, созданные в начале_дня, до 3 часов ночи или начала_дня+180.
@today_records = Temp.where(Time.zone.now.beginning_of_day..Time.zone.now.beginning_of_day+180) работает отлично. Однако мне нужны эти записи для дней, которые не являются Date.current или Time.zone.now или Time.zone.yesterday. Это должен быть день, когда была сделана запись, которая хранится в столбце created_at И date: в таблице.
Я пробовал такие вещи, как @temps = Temp.all, затем @temps.where("created_at ‹= beginnig_of_day+180 AND created_at > begin_of_day"). Что-то вроде этого псевдокода сработало бы, если бы я мог получить правильный синтаксис и/или порядок/размещение.
В таблице есть столбцы даты, temp_high, и я пытался создать записи очень рано утром. Я знаю, что экземпляр Temp, такой как @temp.created_at.beginning_of_day+180, будет 3 часа ночи, если эта запись была создана точно в begin_of_day.
Как я могу использовать это поиск?
Моими моделями являются города и темпы, где города имеют много темпов, а темп принадлежит городу.
class City < ApplicationRecord
has_many :temps
end
class Temp < ApplicationRecord
belongs_to :city
end
create_table "temps", force: :cascade do |t|
t.datetime "date"
t.integer "temp_high"
t.integer "temp_mid"
t.integer "temp_low"
t.bigint "city_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.integer "sunset"
t.index ["city_id"], name: "index_temps_on_city_id"
end
#routes.rb
get "/cities/temps/diff.json", to: 'temps#diff'
#temps_controller
def diff
@cities = City.all
@temps = @cities.map{ |city| city.temps }
@hot = @temps.map{ |temp| temp.map{ |city_temp| city_temp.try(:temp_high) } }
@cool = @temps.map{ |temp| temp.order(created_at: :desc).limit(3) }
render json: {HOTTEST: @hot, COOLEST: @cool }
end
update Приведенный ниже ответ был на самом деле хорошим ответом. В приложении я получаю именно то, о чем прошу: записи, созданные между 00:00 и 3:00. ОДНАКО
Этот запрос должен быть динамическим и меняться в течение указанного дня. Например, каждый день запрос будет получать новые данные и выполнять расчет. Это дает действительно хороший ответ, но он очень статичен.
Можно ли также ввести переменную даты в запрос? Я не мастер sql и только что закончил изучение рельсов.
#<ActiveRecord::Relation [#<Temp id: 5, date: "2020-03-28 09:04:23", temp_high: 42, temp_mid: 35, temp_low: 28, city_id: 3, created_at: "2020-03-28 09:04:24", updated_at: "2020-03-28 09:04:24", sunset: 1585436723, current_temp: 35, sunset_datetime: "2020-03-28 23:05:23">]> 2.6.1 :007 > x[0].created_at Temp Load (0.8ms) SELECT "temps".* FROM "temps" WHERE "temps"."id" = $1 [["id", 5]] => Sat, 28 Mar 2020 02:04:24 MST -07:00
Когда вы работаете с записью напрямую, извлекаете ее из базы данных и спрашиваете, когда она была создана, вы получаете правильное время 02:04:24.
Мне нужно установить часовой пояс в postgresql. Postgesql работает с UTC, и rails преобразует его, как только он будет извлечен из БД.
Я позволяю рельсам преобразовывать их, а затем выполняю расчет после извлечения из базы данных. Это нормально, но я в основном работаю над этой проблемой и делаю менее прямое и более сложное сравнение между записями, а затем выполняю математические операции с записями, включая разницу и скорость (разница/время).
обновление 2
Этот код работает очень хорошо, чтобы делать то, что я изначально хотел. Я так и не решил проблему вытаскивания записей за конкретный день. Это работает только для текущего дня
@afternoon = Temp.where("created_at BETWEEN
date_trunc('day', created_at) + interval '11 hour' AND
date_trunc('day', created_at) + interval '17 hour' ").first(5);
@overnight = Temp.where("created_at BETWEEN
date_trunc('day', created_at) + interval '0 hour' AND
date_trunc('day', created_at) + interval '5 hour' ").first(5);
Этот пост предназначен для образовательных целей для других.