我正在尝试编写一些范围,用于从我的sqlite数据库中提取未来,过去和当前事件的事件。以下是我在Event模型中设置的范围及其附带的谓词方法:
scope :upcoming, where("start_at >= :time", time: Time.current ).order('start_at asc')
scope :recent, where("end_at <= :time", time: Time.current ).order('end_at desc')
scope :current, where("start_at <= :time AND end_at >= :time", time: Time.current ).order('start_at asc')
def upcoming?
start_at.future?
end
def recent?
end_at.past?
end
def current?
end_at.future? && start_at.past?
end
以下是我从我的rspec测试中得到的结果
is in the future
should be upcoming
should not be recent
should not be current
should be in upcoming
should not be in recent (FAILED - 1)
should not be in current (FAILED - 2)
is in the past
should not be upcoming
should be recent
should not be current
should not be in upcoming
should be in recent (FAILED - 3)
should not be in current
is happening now
should not be upcoming
should not be recent
should be current
should not be in upcoming
should not be in recent
should be in current (FAILED - 4)
正如您所看到的,一旦从数据库中提取日期,谓词方法测试运行正常,但实际查询数据库时,事情会变得混乱。
这是我正在运行的测试它的rspec(我对它有点新意,所以这里可能会有一些问题,但我看到范围也因手动测试而失败):
let(:future) { Event.create(start_at: start_time, end_at: end_time ) }
let(:past) { Event.create(start_at: start_time, end_at: end_time ) }
let(:happening) { Event.create(start_at: start_time, end_at: end_time ) }
context "#upcoming?" do
it { should respond_to(:upcoming?) }
end
context "#recent?" do
it { should respond_to(:recent?) }
end
context "#current?" do
it { should respond_to(:current?) }
end
context "is in the future" do
subject(:event) { future }
let(:start_time) { Time.now + 1.minute }
let(:end_time) { Time.now + 1.minute + 1.second }
it { should be_upcoming }
it { should_not be_recent }
it { should_not be_current }
it "should be in upcoming" do
Event.upcoming.should include(event)
end
it "should not be in recent" do
Event.upcoming.should_not include(event)
end
it "should not be in current" do
Event.upcoming.should_not include(event)
end
end
context "is in the past" do
subject(:event) { past }
let(:start_time) { Time.now - 1.minute }
let(:end_time) { Time.now - 1.minute + 1.second }
it { should_not be_upcoming }
it { should be_recent }
it { should_not be_current }
it "should not be in upcoming" do
Event.upcoming.should_not include(event)
end
it "should be in recent" do
Event.upcoming.should include(event)
end
it "should not be in current" do
Event.upcoming.should_not include(event)
end
end
context "is happening now" do
subject(:event) { happening }
let(:start_time) { Time.now - 1.minute }
let(:end_time) { Time.now + 1.minute }
it { should_not be_upcoming }
it { should_not be_recent }
it { should be_current }
it "should not be in upcoming" do
Event.upcoming.should_not include(event)
end
it "should not be in recent" do
Event.upcoming.should_not include(event)
end
it "should be in current" do
Event.upcoming.should include(event)
end
end
知道出了什么问题吗?我尝试了Time.current
的几种变体,它们都产生了类似的结果。
答案 0 :(得分:0)
正如@jdoe在评论中所说,你必须使用lambda来避免Time.current只被提取一次。