Хитрый поиск Active Record. Запись создана между 3 часами утра и началом дня - PullRequest
0 голосов
/ 23 марта 2020

У меня есть приложение для отслеживания температур, связанных с глобальным потеплением.

У меня есть температура записи в базе данных 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. Это должен быть день, когда была сделана запись, которая, как оказалось, хранится в колонке create_at И столбце date: в таблице.

Я пробовал что-то вроде @temps = Temp.all then @ temps.where ("созданный_кат <= beginnig_of_day + 180 И созданный_ат> begin_of_day"). Нечто подобное этому псевдокоду сработало бы, если бы я мог получить правильный синтаксис и / или порядок / размещение.

В таблице есть столбцы date, temp_high, и я пытался получить записи, созданные очень рано утром. Я знаю, что экземпляр Temp, такой как @ temp.created_at.beginning_of_day + 180, будет в 3 часа ночи, если эта запись была создана точно в начале_дня.

Как я могу использовать этот поиск?

Моими моделями являются город и температура, в которых города имеют много временных значений, а температура принадлежит городу

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 

обновление Приведенный ниже ответ был фактически хорошим ответом. В приложении я получаю именно то, что запрашиваю: записи, созданные между 0000 и 3 часами утра. HOWEVER

Этот запрос должен быть динамическим c и изменяться в соответствии с указанным днем. Например, каждый день там запрос будет принимать новые данные и делать расчеты. Это дает действительно хороший ответ, но это очень важно c.

Может ли переменная даты также быть вставлена ​​в запрос? Я не мастер 1045 * и только что закончил изучать рельсы.

#<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 * 1029. *

Я должен установить часовой пояс в postgresql. Postge sql работает на UT C и rails преобразует это, как только оно будет извлечено из БД

Я разрешаю рельсам преобразовать их, а затем делаю вычисления после того, как вытащил их из БД. Это хорошо, но я в основном работаю над этой проблемой и делаю менее прямое и более сложное сравнение между записями, а затем делаю математические расчеты с записями, включая разницу и скорость (разница / время).

обновление 2

Этот код работает очень хорошо, чтобы делать то, что я изначально хотел. Я не решил проблему извлечения записей за определенный c день. Это работает только на текущий день

    @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);

Эта публикация предназначена для образовательных целей.

1 Ответ

0 голосов
/ 23 марта 2020

Я думаю, что это может работать нормально.

Temp.where("created_at BETWEEN 
            date_trunc('day', created_at) + interval '1 day' - interval '24 hour' AND 
            date_trunc('day', created_at) + interval '1 day' - interval '21 hour' ")

Если вам не подходит этот интервал, вы можете поиграть с операторами >= и <.

...