简体   繁体   English

使用Timecop gem for Scopes

[英]Using Timecop gem For Scopes

I'm spec'ing a scope in a Rails 3.0 app as follows: 我在Rails 3.0应用程序中指定了一个范围,如下所示:

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

In my spec, I want to do: 在我的规范中,我想做:

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

As you might imagine, the puts really shows that Date.today is two days hence. 正如您可能想象的那样,看跌期权真的表明Date.today是两天。 However, the scope is evaluated in a different context, so it uses the old "today". 但是,范围是在不同的上下文中进行评估的,因此它使用旧的“今天”。 How does one get today evaluated in a context that Timecop can affect. 今天如何在Timecop可以影响的上下文中进行评估。

Thanks! 谢谢!

This is a really common mistake. 这是一个非常常见的错误。 As you've written in the date used by the scope is the date as it was when the code was loaded. 正如您在范围使用的日期所写的那样,是加载代码时的日期。 Were you to run this in production where code is only reloaded if you restart the app (unlike development where it is reloaded on each request), you'd get the right results on the day you restarted the app, but the next day the results would be out by one day, the day after by 2 days etc. 如果你重新启动应用程序(不像每次请求重新加载的开发),你是否只在重新加载代码的生产中运行它,你会在重新启动应用程序的那天获得正确的结果,但第二天结果将在一天之内,第二天之后出现等等。

The correct way of defining a scope like that is 定义这样的范围的正确方法是

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

The lambda ensures that those dates are evaluated each time the scope is used. lambda确保每次使用范围时评估这些日期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM