2009-11-09 24 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来处理尺寸未定义的故障情况。

相关问题