Ruby on rails Rails中的ActiveRecord时间比较
我试图编写一些作用域,用于从我的sqlite数据库中提取未来、过去和当前事件的事件。以下是我在事件模型中设置的范围及其附带的谓词方法:Ruby on rails Rails中的ActiveRecord时间比较,ruby-on-rails,sqlite,activerecord,time,Ruby On Rails,Sqlite,Activerecord,Time,我试图编写一些作用域,用于从我的sqlite数据库中提取未来、过去和当前事件的事件。以下是我在事件模型中设置的范围及其附带的谓词方法: 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') s
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来测试itI,我对它有点陌生,所以这里可能有一些问题,但我也看到了手动测试失败的范围:
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,它们都产生了类似的结果。正如@jdoe在他的评论中所说的,你必须使用lambda来避免Time.current只被获取一次。首先:通过lambda创建你的作用域。您的方式Time.current将被获取一次,并将一直保持程序运行,这显然不是您想要的。这可能是一次抓取时间的问题。我以前也试过,但结果却出现了更多的错误。但是我知道lambda不可能是一件坏事,所以我将更新问题中的代码和测试。您必须以这种方式使用lambda:scope:uncoming,lambda{where…}。谢谢,我已经尝试过了,现在回到了最初失败的地方:
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