如果验证失败,您可以重置ActiveRecord实例吗?

时间:2014-11-08 20:21:38

标签: ruby-on-rails ruby validation rails-activerecord

我们假设您有一个年龄属性不能为负的用户

class User < ActiveRecord::Base
  validates :age, numericality: { greater_than: 0 }
end

如果您尝试将属性更新为否定数,则验证将失败,但实例仍将具有负年龄值

#<User id: 1, age: 5, created_at: "2014-11-08 20:14:12", updated_at: "2014-11-08 20:14:12">
user.update_attributes!(:age => -5)
#<User id: 1, age: -5, created_at: "2014-11-08 20:14:12", updated_at: "2014-11-08 20:14:12">

除了捕获ActiveRecord :: RecordInvalid并重置该值之外,如果它的验证失败,它们是一种重置实例的方法吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

如果验证失败,您可以致电model.reload。所以它看起来像:

if @model.update_attributes(age: params[:age]) # params[:age] = -5 for example
  # model is valid and saved, continue...
else # update_attributes return false and will not raise an exception if model is invalid
  # model is invalid, reloading...
  @model.reload
  # if we call @model.age now, it will return previous value
end

无论如何,update_attributes将设置属性,即使模型在更新后变得无效,尽管它不会将无效属性持久化到数据库。但请记住,它会重置此调用中可能已执行的所有其他更改,因此update_attributes(name: params[:name], age: params[age])将重置名称和年龄,即使名称有效。

答案 1 :(得分:1)

我想说你需要一个自定义验证器,例如:

class MyValidator < ActiveModel::Validator

  def validate(record)
    unless record.age.to_i > 0
      record.errors[:name] << 'Invalid!'
      record.age = record.age_was # Rewrite new with old value
    end
  end
end

class Person
  include ActiveModel::Validations
  validates_with MyValidator
end

使用ActiveModel::Dirty,无需重新加载。