且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

错误不会阻止对象保存?

更新时间:2023-11-29 23:25:52

调用 t.valid? 将在运行验证之前清除错误,以便您在 time_range= 内进行验证被忽略.

Calling t.valid? will clear the errors before running the validations so your validations inside time_range= are ignored.

如果我们查看 ActiveRecords的valid?,我们看到这个:

If we look at ActiveRecords's valid?, we see this:

def valid?(context = nil)
  context ||= (new_record? ? :create : :update)
  output = super(context)
  #...

超级应该把你送到ActiveModel 的 valid? 开头是这样的:

And the super should send you into ActiveModel's valid? which starts like this:

def valid?(context = nil)
  current_context, self.validation_context = validation_context, context
  errors.clear
  #...

clear 调用会消除您在 time_range= 中添加的错误.

and the clear call nukes the errors you added in time_range=.

如果您想验证某些内容,请使用验证器.如果您想防止无效分配,请引发 ArgumentError(或其他更合适的例外).

If you want to validate something, use the validators. If you want to prevent an invalid assignment, raise an ArgumentError (or other more appropriate exception).

在运行验证之前让验证系统自行重置(即 errors.clear)确实有意义.如果它没有重置,则您必须丢弃并重新加载无效对象(或手动重置它)以纠正验证错误.仅仅因为更新、验证、保存或销毁"是网络应用程序的一般工作流程,并不意味着它是数据库支持的应用程序唯一可能的工作流程.

Having the validation system reset itself (i.e. errors.clear) before running the validations does make sense. If it didn't reset, you'd have to throw away and reload an invalid object (or manually reset it) just to correct a validation error. Just because "update, validate, save or destroy" is the general workflow for a web-app doesn't mean that it is the only possible workflow for a database-backed application.