我有一个具有开始日期和结束日期的用户事件的以下模型,我写了一些方法来验证开始和结束日期以及它们之间的关系
class Event < ActiveRecord::Base
attr_accessible :start, :finish
validate :must_start_now_or_in_future,
:must_have_a_start_if_has_an_end,
:start_and_end_must_not_be_equal,
:must_have_valid_start,:must_have_valid_finish
def must_start_now_or_in_future
if start
if start.to_time.to_i < DateTime.now.to_time.to_i
errors.add(:start,'Start date must be in the future')
end
end
end
def must_have_a_start_if_has_an_end
if !start && finish
errors.add(:end,'Start date must also be specified if finish date is specified')
end
end
def start_and_end_must_not_be_equal
if start && finish
if start.to_time.to_i == finish.to_time.to_i
errors.add(:start, 'Start and finish dates cannot be the same')
end
end
end
def must_have_valid_start
if start
begin
DateTime.parse(start.to_s)
rescue
errors.add(:start, 'Start and finish dates must be valid')
end
end
end
def must_have_valid_finish
if finish
begin
DateTime.parse(finish.to_s)
rescue
errors.add(:finish, 'Start and finish dates must be valid')
end
end
end
end
我还写了RSpec测试,看看验证是否正确执行
require 'spec_helper'
require 'date'
describe Event do
before(:each) do
@attr = {:start=>DateTime.now, :finish=>2.days.from_now}
end
it "should create an instance with valid attributes" do
event = Event.create!(@attr)
end
it "should create an instance if start and/or end are nil" do
Event.create!(@attr.merge({:start=>nil,:finish=>nil}))
Event.create!(@attr.merge({:finish=>nil}))
end
it "should start now or in the future" do
past = Event.new(@attr.merge({:start=>2.days.ago}))
past.should_not be_valid
end
it "should have a start if it has an end" do
no_start_but_end_event = Event.new(@attr.merge({:start=>nil}))
no_start_but_end_event.should_not be_valid
end
it "should not have equal start and end dates" do
equal_start_and_end = Event.new(@attr.merge({:finish=>DateTime.now}))
equal_start_and_end.should_not be_valid
end
it "should not have invalid start date" do
invalid_start = Event.new(@attr.merge({:start=>'abcdef'}))
invalid_start.should_not be_valid
end
it "should not have invalid finish date" do
invalid_end = Event.new(@attr.merge({:finish=>'abcdef'}))
invalid_end.should_not be_valid
end
end
由于某种原因,“不应该有无效的完成日期”测试会一直失败,因为它将invalid_end变量视为有效。我只是无法弄清楚为什么,即使一切似乎都是正确的。我哪里错了?
答案 0 :(得分:1)
我认为ActiveRecord会默默地丢弃您的无效日期信息,因此if finish
阻止了:finish
,因为nil
仍然是{{1}}。尝试在该行之前和之后添加println或断点,以验证您是否实际进入该块。