Как использовать: условия для сравнения (дата-время) с (дата-время + «количество дней»)? - PullRequest
0 голосов
/ 28 августа 2010

Я создаю приложение, которое проверяет, когда пользователь должен заменить масло в одной из своих машин. Вот как это работает:

  1. Пользователь вводит название своего автомобиля (например, «Ford Mustang»)
  2. Пользователь вводит время, когда автомобиль будет работать на одной смене масла (например, 3 месяца)
  3. Пользователь сохраняет автомобиль в базу данных
  4. Повторите описанный выше процесс для всех остальных своих автомобилей. (Да, это богатый пользователь;)

Теперь, когда пользователь возвращается на сайт, он хочет увидеть список всех своих автомобилей, которые нуждаются в замене масла. Затем он меняет масло и обновляет свойство 'oil_changed_at'.

Я использую следующие столбцы для модели автомобиля:

title:string
oil_changed_at:datetime
oil_expiration_timeframe:integer

Мой вопрос: Каков предпочтительный способ хранения этого 'oil_expiration_timeframe' и как должны выглядеть мои условия: когда я хочу получить список всех автомобилей, которые нуждаются в замене масла?

Имейте в виду, что значение oil_expiration_timeframe может варьироваться от нескольких дней до нескольких лет. Это никогда не будет меньше дня, поэтому я думаю, что могу просто хранить количество дней в этом поле. Однако я не уверен, как объединить целое число и дату и время в запросе.

Ответы [ 4 ]

1 голос
/ 28 августа 2010

Это действительно вопрос знания ряда функций даты SQL.В MySQL это выглядело бы так:

:conditions => 
  "DATE_ADD(DATE(oil_changed_at),
            INTERVAL oil_expiration_timeframe DAY) <= CURDATE()"

Единственный недостаток этого способа - отсутствие хорошего способа оптимизации этого запроса.Если производительность становится проблемой, может быть проще всего сохранить текущую дату истечения срока действия в базе данных.

1 голос
/ 28 августа 2010

Если вы индексируете свой столбец oil_changed_at, эффективен следующий подход.

Car.all(:conditions => [
  "oil_changed_at > DATE_SUB(?, INTERVAL oil_expiration_timeframe day)", Time.now
])

Лучше было бы добавить новый столбец (next_oil_change_date) к модели автомобиля, чтобы сохранить дату следующей замены масла и обновить столбец при изменении модели автомобиля.

class Car < ActiveRecord::Base
  before_save :set_next_oil_change_date

  def set_next_oil_change_date
    self.next_oil_change_date = next_oil_change_date + 
                                  oil_expiration_timeframe.days
  end
end

Теперь вы можете написать свой запрос как:

Car.all(:conditions => [
  "next_oil_change_date > ? ", Time.now
])

Не забудьте проиндексировать столбец next_oil_change_date.

0 голосов
/ 28 августа 2010

Основываясь на коде запроса MySQL от wuputah, я придумал следующее для SQLite:

:conditions => 'date(oil_changed_at, oil_expiration_timeframe||" days") <= date("now")'

Конечно, подход, не зависящий от базы данных, все еще предпочтителен.

0 голосов
/ 28 августа 2010

Добавление числа в DateTime добавляет столько дней к дате. Например:

irb(main):005:0> DateTime.now.to_s
=> "2010-08-27T18:32:36-06:00"
irb(main):006:0> (DateTime.now + 7).to_s
=> "2010-09-03T18:32:48-06:00"

Поэтому я бы предложил придерживаться вашего первоначального плана сохранения смещения в виде количества дней.

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