我有一个标准的活动记录模型,其中包含所需的属性:
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 方法需要 size 属性,但执行的结果也需要验证。在上述情况下, size 在验证其存在之前使用。
我可以将实例设置为无效并在完成所有验证后停止保存过程吗?
答案 0 :(得分: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来处理未定义大小的故障情况。
答案 1 :(得分:0)
我假设您希望number_of_colors
方法在grab_colors
方法之后运行。在这种情况下,我建议按照validate
方法按顺序调用这两种方法。
def validate
unless size.blank?
grab_colors
number_of_colors
end
end
尺寸验证仍由
处理validates_presence_of :size
但如果您的尺码为grab_colors
且number_of_colors
,则会运行。现在你不需要这些行
before_validation :grab_colors
validate :number_of_colors