I have a problem where an :if clause within an ActiveRecord validation is not being honoured.
My model has an ip_port attribute which I am validating as being present, numeric and within a certain range. I am trying to ensure that each condition only generates one error. I do not want the situation where an empty attribute results in three messages displayed to the user stating that it is not present, required and not numeric.
This is my model as it stands
class Arc < ActiveRecord::Base
attr_accessible :ip_port
validates_presence_of :ip_port
validates_numericality_of :ip_port, :allow_blank => true
validates_inclusion_of :ip_port, :in => 1025..65535, :allow_blank => true,
:if => Proc.new {|arc| arc.ip_port.to_s.match(/^\d+$/) }
end
And this is my model spec and its results.
describe Arc do
it "should be valid with valid attributes" do
Arc.new(:ip_port => 1200).should be_valid
end
it "should be invalid with a non-numberic port" do
Arc.new(:ip_port => "test").should be_invalid
end
it "should be invalid with a missing port" do
Arc.new(:ip_port => nil).should be_invalid
end
it "should have one error with a missing port" do
a = Arc.new(:ip_port => nil)
a.should be_invalid
a.should have(1).errors_on(:ip_port)
end
it "should have one error with a non-numeric port" do
a = Arc.new(:ip_port => "test")
a.should be_invalid
a.should have(1).errors_on(:ip_port)
end
it "should have one error with a numeric port outside the range" do
a = Arc.new(:ip_port => 999)
a.should be_invalid
a.should have(1).errors_on(:ip_port)
end
end
Arc - should be valid with valid attributes - should be invalid with a non-numberic port - should be invalid with a missing port - should have one error with a missing port - should have one error with a non-numeric port (FAILED - 1) - should have one error with a numeric port outside the range 1) 'Arc should have one error with a non-numeric port' FAILED expected 1 errors on :ip_port, got 2 ./spec/models/arc_spec.rb:21: Finished in 0.108245 seconds
My question is why I am getting two errors for a non-numeric ip_port when the :if clause should prevent the validates_inclusion of from being called.
This is Rails 2.3.5 with Ruby 1.8.7 on OS/X 10.6.3