Использование драгоценного камня Timecop For Scopes - PullRequest
6 голосов
/ 13 января 2012

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

class DrawingList < ActiveRecord::Base
  scope :active_drawings, where('start_date <= ? AND end_date >= ?', Date.today, Date.today)
end

В своей спецификации я хочу сделать:

before do
  @list = DrawingList.create #things that include begin and end dates
end

it "doesn't find an active drawing if they are out of range" do
  pending "really need to figure out how to work timecop in the presence of scopes"
  Timecop.travel(2.days)
  puts Date.today.to_s
  DrawingList.active_drawings.first.should be_nil
end

Как вы можете себе представить, путы действительно показывают, что Date.today - это два дня спустя.Однако область действия оценивается в другом контексте, поэтому она использует старое «сегодня».Как можно сегодня оценить в контексте, на который может повлиять Timecop.

Спасибо!

1 Ответ

18 голосов
/ 13 января 2012

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

Правильный способ определения такой области:

scope :active_drawings, lambda { where('start_date <= ? AND end_date >= ?', Date.today, Date.today)}

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

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