2009-12-22 82 views
21

首先,讓我說我是極其新新的Rails(玩弄它一兩次,但迫使我自己現在寫一個完整的項目,昨天開始)。驗證模型屬性大於另一個

我現在試圖驗證模型屬性(術語?)是否比另一個更大。這似乎是validates_numericality_ofgreater_than選項的完美實例,但可惜的是,這會引發錯誤,告訴我greater_than expects a number, not a symbol。如果我嘗試鍵入該符號.to_f我收到undefined method錯誤。

這是我最終做的,我很好奇是否有更好的方法。這只是一個控制項目發佈的簡單系統,我們只有大/小版本(單點),所以float在這裏感覺像是正確的決定。

class Project < ActiveRecord::Base 
    validates_numericality_of :current_release 
    validates_numericality_of :next_release 
    validate :next_release_is_greater 

    def next_release_is_greater 
     errors.add_to_base("Next release must be greater than current release") unless next_release.to_f > current_release.to_f 
    end 
end 

這工作 - 它傳遞相關的單元測試(以下爲您的觀賞樂趣),我只是好奇,如果有一個更簡單的方法 - 這是我可以嘗試其他方式。

相關的單元測試:

# Fixture data: 
# PALS: 
#  name: PALS 
#  description: This is the PALS project 
#  current_release: 1.0 
#  next_release: 2.0 
#  project_category: 1 
#  user: 1 
def test_release_is_future 
    project = Project.first(:conditions => {:name => 'PALS'}) 
    project.current_release = 10.0 
    assert !project.save 

    project.current_release = 1.0 
    assert project.save 
end 

回答

19

正如您注意到的,唯一的方法是使用自定義驗證器。 :greater_than選項應該是一個整數。以下代碼將不起作用,因爲當前版本和下一版本僅在實例級別可用。

class Project < ActiveRecord::Base 
    validates_numericality_of :current_release 
    validates_numericality_of :next_release, :greater_than => :current_release 
end 

greater_than該選項的目的是爲了驗證對靜態常數或其它類的方法的值。

因此,不要介意並繼續使用您的自定義驗證程序。 :)

+0

出色答卷,詳細的迴應 - 我需要的(加少許安慰)。 – 2009-12-22 16:05:11

+0

很好的答案,當你有機會「greather_than」時,請修復拼寫錯誤。再次感謝。 – ghayes 2011-08-09 06:02:10

+0

完成,謝謝。 – 2011-08-09 08:48:19

0

這是執行自定義驗證的最佳途徑,但是,您可能想看看像factory_girl作爲替代固定裝置(它看起來像您正在使用):然後

http://github.com/thoughtbot/factory_girl

單元測試會是什麼樣子:

def test_... 
    Factory.create(:project, :current_release => 10.0) 
    assert !Factory.build(:project, :current_release => 1.0).valid? 
end 
4

使用Rails 3.2,您可以通過傳遞一個proc來實時驗證兩個字段。

validates_numericality_of :next_release, :greater_than => Proc.new {|project| project.current_release } 
6

validates_numericality_of接受a large list of options和它們中的一些可以與PROC或符號被提供(這意味着可以基本通過一個屬性或整個方法)。

驗證屬性的numericality比另一值更高:

class Project < ActiveRecord::Base 
    validates_numericality_of :current_release, less_than: ->(project) { project.next_release } 

    validates_numericality_of :next_release, 
    greater_than: Proc.new { project.current_release } 
end 

爲了澄清,任何這些選項可以接受一個PROC或符號:

  • :greater_than
  • :greater_than_or_equal_to
  • :equal_to :less_than
  • :less_than_or_equal_to

validates_numericality文檔:http://api.rubyonrails.org/classes/ActiveModel/Validations/HelperMethods.html#method-i-validates_numericality_of

使用特效與驗證: http://guides.rubyonrails.org/active_record_validations.html#using-a-proc-with-if-and-unless

相關問題