0

对于具有开始日期和结束日期的用户事件,我有以下模型,并且我编写了一些方法来验证开始日期和结束日期以及它们之间的关系

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 变量视为有效。我只是不知道为什么,即使一切似乎都是正确的。我哪里错了?

4

1 回答 1

1

我相信 ActiveRecord 会默默地丢弃您的无效日期信息,因此您的if finish块正在跳过,因为:finishis still nil. 尝试在该行之前和之后添加一个 println 或断点,以验证您是否确实进入了该块。

于 2013-06-06T18:51:43.680 回答