Reputation: 1033
I have the following model for a user event that has a start date and a finish date, and I wrote some methods for validating start and finish dates and the relationship between them
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
I also wrote RSpec tests to see if the validation was being performed correctly
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
For some reason, the "should not have invalid finish date" test keeps failing because it is treating the invalid_end variable as valid. I just can't figure out why, even though everything seems to be correct. Where am I going wrong?
Upvotes: 0
Views: 4232
Reputation: 1051
I believe ActiveRecord is silently discarding your invalid date info, and so your if finish
block is skipping because :finish
is still nil
. Try adding a println or breakpoint before and after that line to verify you're actually entering the block.
Upvotes: 1