Rails模型.有效吗?刷新自定义错误并错误地返回true

Dam*_*che 28 activerecord ruby-on-rails

我试图将自定义错误添加到我的用户模型的实例,但是当我调用有效时?它正在擦除自定义错误并返回true.

[99] pry(main)> u.email = "test@test.com"
"test@test.com"

[100] pry(main)> u.status = 1
1

[101] pry(main)> u.valid?
true

[102] pry(main)> u.errors.add(:status, "must be YES or NO")
[
    [0] "must be YES or NO"
]

[103] pry(main)> u.errors
#<ActiveModel::Errors:[...]@messages={:status=>["must be YES or NO"]}>

[104] pry(main)> u.valid?
true

[105] pry(main)> u.errors
#<ActiveModel::Errors:[...]@messages={}>
Run Code Online (Sandbox Code Playgroud)

如果我validate在模型中使用该方法,那么它可以工作,但是这个特定的验证是从不同的方法中添加的(这需要传递参数):

User

def do_something_with(arg1, arg2)
  errors.add(:field, "etc") if arg1 != arg2
end
Run Code Online (Sandbox Code Playgroud)

由于上述原因,user.valid?即使将错误添加到实例,也会返回true.

Yan*_*hao 45

在ActiveModel中,valid?定义如下:

def valid?(context = nil)
  current_context, self.validation_context = validation_context, context
  errors.clear
  run_validations!
ensure
  self.validation_context = current_context
end
Run Code Online (Sandbox Code Playgroud)

因此预期存在的错误被清除.您必须将所有自定义验证放入一些validate回调中.像这样:

validate :check_status

def check_status
  errors.add(:status, "must be YES or NO") unless ['YES', 'NO'].include?(status)
end
Run Code Online (Sandbox Code Playgroud)

  • 在这种情况下,`?` 方法改变了它被调用的对象的状态,这是否令人惊讶? (5认同)