2009-11-09 23 views
1

我有所需的屬性的標準的活動記錄模式:如何在驗證運行之後但保存之前將模型實例設置爲無效?

class Sample < ActiveRecord::Base 
    has_many :colors 

    before_validation :grab_colors 

    validates_presence_of :size 
    validate :number_of_colors 

    private 

    def grab_colors 
    # grab x number of colors | x = size 
    end 

    def number_of_colors 
    self.errors.add("size","is to large.") if colors.count < size 
    end 
end 

我的問題是,grab_colors方法需要大小屬性,但執行的是需要被驗證以及結果。在以上的情況下,在其存在被驗證之前使用大小

我可以將實例設置爲無效並在所有驗證完成後停止保存過程?

回答

0

我假設您想在grab_colors方法之後運行number_of_colors方法。在這種情況下,我建議從validate方法中按順序調用這兩種方法。

def validate 
    unless size.blank? 
    grab_colors 
    number_of_colors 
    end 
end 

大小的驗證仍然由

validates_presence_of :size 

但是處理,如果您有大小,然後grab_colorsnumber_of_colors運行。現在你不需要這些線

before_validation :grab_colors 
validate :number_of_colors 
1

有幾種方法可以做到這一點,但它們都涉及重寫grab_colors來執行validates_presence_of檢查。

您正在設置before_validation回調。任何返回false的回調將取消剩餘的交易。所以你需要處理這種情況,使得grab_colors自己失敗。本質上你要求這樣的事情:

def grab_colors 
    unless size.blank? 
    # grab x number of colors | x = size 
    else 
    errors.add(:size, "cannot be empty.") 
    return false 
    end 
end 

這合併您的自定義before_validation與validates_presence_of。當size不存在時,grab_colors會設置一個錯誤並返回false,取消事務的其餘部分,所以您的標準驗證將永遠不會執行。從你所提到的情況來看,唯一一次失敗的時候是大小未設置的時候。

您還可以通過讓number_of_colors調用grab_colors而不是調用grab_colors作爲before_validation來達到預期的效果。不過,您仍然需要調整grab_colors來處理尺寸未定義的故障情況。

相關問題