2010-07-01 43 views
2

我有一個問題,其中:在一個ActiveRecord驗證中的if子句不被遵守。爲什麼:如果沒有被ActiveRecord驗證識別?

我的模型有一個ip_port屬性,我正在驗證是存在的,數字和在一定範圍內。我試圖確保每個條件只會產生一個錯誤。我不希望出現這樣的情況:空屬性導致向用戶顯示三條消息,說明它不存在,不是必需的,也不是數字。

這是我的模型,因爲它代表

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 

這是我的模型規範,其結果。

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 

我的問題是爲什麼我收到兩個錯誤的非數字ip_port時:如果條款應防止被稱爲validates_inclusion。

這是Rails的2.3.5和Ruby 1.8.7上的OS/X 10.6.3

回答

2

雖然有沉思漫步我已經解決我自己的問題。

問題是,爲了驗證範圍內的包含,它將提供的值轉換爲int,然後檢查包含。所以對於一個非數字值,我會得到一個:not_a_number和一個:包含錯誤。

答案是修改:如果子句中使用的價值它是類型轉換之前,所以我validates_inclusion_of方法變得

validates_inclusion_of :ip_port, :in => 1025..65535, :allow_blank => true, 
    :if => Proc.new {|arc| arc.ip_port_before_type_cast.to_s.match(/^\d+$/) } 

然後,這讓我對每三個條件之一的錯誤。

+0

如果在使用類型轉換之前使用該值,還需要to_s嗎? (不是說你肯定是錯的 - 只是要求我自己的無知) – Chowlett 2010-07-01 09:58:44

+0

@Chris。是的你是。如果ip_port屬性被分配了一個整數,那麼驗證將失敗,因爲Fixnum上的匹配將失敗。 – 2010-07-01 10:11:03

+0

啊,當然,因爲這是*寫入*數據庫。繼續探索我的知識範圍 - *爲什麼數值驗證在使用arc.ip_port時觸發? – Chowlett 2010-07-01 11:50:03

相關問題