使用部分失败的验证保存模型

时间:2013-09-05 18:44:20

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.2 rails-activerecord

假设我有以下型号:

class Car < ActiveRecord::Base

attr_accessible :wheels,
                :engine_cylinders

validates :wheels, :engine_cylinders, presence: true, numericality: true

end

假设我接下来有以下控制器操作:

@car = Car.find(params[:id])
@car.wheels = "foo"
@car.engine_cylinders = 4
@car.save

此保存将失败,因为车轮将无法通过数值条件。

是否有任何方法可以保留成功的属性(在本例中为engine_cylinders),同时将无效属性添加到errors数组中?例如。 Rails中有“软”验证吗?

3 个答案:

答案 0 :(得分:1)

您想要撰写 Custom Validator

class Car < ActiveRecord::Base
  validate :wheel_range,
           :engine_cylinder_range

  def engine_cylinder_range
    flash[:notice] = "engine_cylinder was not saved because it wasn't a number" unless engine_cylinder.is_a? Fixnum
    # set engine_cylinder back to old value
  end

  def wheel_range
    flash[:notice] = "wheels was not saved because it wasn't a number" unless wheels.is_a? Fixnum
    # set wheels back to old value
  end
end

您不必在此处使用flash,您可以使用任何变量进行内部处理或重新显示。

您可能还想在:before_save hook上进行此自定义验证检查。使用_was magic method获取旧值。

答案 1 :(得分:0)

如果您希望绕过验证,可以随时使用:

if @car.save
  # ...
else
  @car.save(validate: false)
end

您可能希望对此有什么不同的条件......但这就是您在一次性基础上绕过验证的方式。

然而,这可能会破坏错误数组,因此您可以在save(validate: false)之后重建它:

@car.valid?

您还可以使用@car.update_attribute(:attribute, <value>)一次一个地绕过验证。

答案 2 :(得分:0)

如果您只是想知道模型是否有效而没有保存,@car.valid?就是这样做的。它还会向errors数组添加无效属性。 @pdobb已经指出了如何在保存时绕过验证。