Dennis Hackethal
Dennis Hackethal

Reputation: 14275

Comparing dates: "comparison of Date with nil failed"

I have a Client model which has many projects. In the project model I want to validate that the project start date is always before or on the same day as the project end date. This is my project model:

class Project < ActiveRecord::Base
  attr_accessible :end_on, :start_on, :title

  validates_presence_of :client_id, :end_on, :start_on, :title
  validate :start_has_to_be_before_end

  belongs_to :clients

  def start_has_to_be_before_end
    if start_on > end_on
        errors[:start_on] << " must not be after end date."
        errors[:end_on] << " must not be before start date."
    end
  end
end

My application works as expected and gives me the specified errors in case the validation fails.

However, in my unit test for the projects, I am trying to cover this scenario, deliberately setting the start date after the end date:

test "project must have a start date thats either on the same day or before the end date" do
    project = Project.new(client_id: 1, start_on: "2012-01-02", end_on: "2012-01-01", title: "Project title")
    assert !project.save, "Project could be saved although its start date was after its end date"
    assert !project.errors[:start_on].empty?
    assert !project.errors[:end_on].empty?
end

Strangely, running this test gives me three errors, all referring to this line if start_on > end_on in my validation method, saying undefined method '>' for nil:NilClass twice and comparison of Date with nil failed once.

What can I do to make the tests pass?

Upvotes: 0

Views: 1908

Answers (1)

Philip Hallstrom
Philip Hallstrom

Reputation: 19879

You are creating a Project that has string values for :start_on and :end_on. That's unlikely to work. Rails might try to be smart and parse those, I'm not sure.. I wouldn't count on it. Odds are some coercion is going on and the values are getting set to nil.

I would do this:

project = Project.new(client_id: 1, 
                      start_on: 2.days.from_now.to_date, 
                      end_on: Time.now.to_date, 
                      title: "Project title")

Upvotes: 1

Related Questions