我有一个虚拟属性,它从表单字段获取时间范围并将其分割:
def time_range=(time_range)
unless time_range.empty?
t = time_range.split(/to|\-/)
self.start_entry = t[0]
self.finish_entry = t[1]
if Chronic.parse(self.start_entry).nil? || Chronic.parse(self.finish_entry).nil?
errors.add(:time_range, 'Invalid time range entered')
end
end
end
start_entry
and finish_entry
也是虚拟属性,因为我有其他方法来设置它们。无论两者如何设置,我都需要设置以下钩子start
and finish
在我的数据库中:
before_save :set_start_and_finish
尽管我添加了一个错误,但错误的对象仍然设法保存:
> t = Tour.new
> t.time_range = "rubbish"
> t.errors
#=> {:time_range=>["Invalid time range entered"]}
> t.valid?
#=> true
如何使实例无效以防止稍后保存?
Calling t.valid?
将在运行验证之前清除错误,以便您在其中进行验证time_range=
被忽略。
如果我们看一下ActiveRecords 的valid? https://github.com/rails/rails/blob/4-0-stable/activerecord/lib/active_record/validations.rb#L68,我们看到这个:
def valid?(context = nil)
context ||= (new_record? ? :create : :update)
output = super(context)
#...
超级应该送你进入活动模型的valid? https://github.com/rails/rails/blob/4-0-stable/activemodel/lib/active_model/validations.rb#L311它是这样开始的:
def valid?(context = nil)
current_context, self.validation_context = validation_context, context
errors.clear
#...
and the clear
调用 nukes 您添加的错误time_range=
.
如果您想验证某些内容,请使用验证器。如果您想防止无效分配,请提出参数错误 http://www.ruby-doc.org/core/classes/ArgumentError.html(或其他更合适的例外)。
让验证系统自行重置(即errors.clear
)在运行验证之前确实有意义。如果它没有重置,您就必须丢弃并重新加载无效对象(或手动重置它)才能纠正验证错误。仅仅因为“更新、验证、保存或销毁”是 Web 应用程序的一般工作流程,并不意味着它是数据库支持的应用程序唯一可能的工作流程。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)