Как сравнить строку с датами в предложении поиска? - PullRequest
0 голосов
/ 26 августа 2010

Я хочу получить модели, дата которых находится в пределах диапазона дат. Поэтому я хочу сделать что-то вроде

MyModel.find_all_by_field1_id_and_field2_id(value1, value2, :conditions => { :date => nb_days_ago..Date.yesterday })

Дело в том, что атрибутом даты моей модели является строка (в формате "08-24-2010"), и я не могу это изменить. Таким образом, чтобы сравнить это с моим диапазоном дат, я попробовал это:

MyModel.find_all_by_field1_id_and_field2_id(value1, value2, :conditions => { Date.strptime(:date, "%m-%d-%Y") => nb_days_ago..Date.yesterday })

Но я получаю ошибку, которая в основном говорит о том, что strptime не может обработать символ: date. Я думаю, что мое решение не очень хорошее.

Как я могу сравнить мою строку с моим диапазоном дат?

Спасибо

Ответы [ 2 ]

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

Вы должны преобразовать строку БД в дату в базе данных, а не в код Ruby:

Model.all(:conditions => [ "STR_TO_DATE(date,'%m-%d-%Y') BETWEEN ? AND ? ",
               nb_days_ago, Date.yesterday])

Лучшее решение - нормализовать вашу модель, добавив теневое поле.

class Model

  after_save :create_shadow_fields
  def create_shadow_fields
    self.date_fld = Date.strptime(self.date_str, "%m-%d-%Y")
  end
end

Теперь ваш запрос можно записать следующим образом:

Model.all(:conditions => {:date_fld => nb_days_ago..Date.yesterday})

Не забудьте добавить индекс для столбца date_fld.

Редактировать 1

Для SQLLite первое решение можно переписать следующим образом:

Model.all(:conditions => [ "STRFTIME('%m-%d-%Y', date) BETWEEN ? AND ? ",
               nb_days_ago, Date.yesterday])
0 голосов
/ 26 августа 2010

Прежде всего, я не завидую вашей ситуации. Это довольно уродливый формат даты. Единственное, о чем я могу думать, - это создать массив строк в этом формате, представляющих ВСЕ дни между датой начала и датой окончания, а затем использовать синтаксис SQL «IN», чтобы найти даты в этом наборе (что можно делать из ActiveRecord: условия условия).

Например, если вы хотите выполнить поиск 10 дней назад:

num = 10 #number of days ago for search range
# range starts at 1 because you specified yesterday
matching_date_strings = (1..num).to_a.map{|x| x.days.ago.strftime("%m-%d-%Y")}
=> ["08-24-2010", "08-23-2010", "08-22-2010", "08-21-2010", "08-20-2010"]
# then...
records = MyModel.all(:conditions => { :date => matching_date_strings })
# or in your case with field1 and field2
records = MyModel.find_all_by_field1_id_and_field2_id(value1, value2, :conditions => { :date => matching_date_strings })

Идея в том, что это должно генерировать SQL с чем-то вроде "... WHERE date IN (" 08-24-2010 "," 08-23-2010 "," 08-22-2010 "," 08-21- 2010 "," 20-20-2010 ")

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