我有以下带有虚拟属性的模型
class Mytimeperiod < ActiveRecord::Base
validates presence of :from_dt
validates_format_of :from_dt, :with => /\A\d{2}\/\d{2}\/\d{4}\Z/, :message => "format is mm/dd/yyyy"
def from_dt
self.from_date.strftime("%m/%d/%Y") if !self.from_date.blank?
end
def from_dt=(from_dt)
self.from_date = Date.parse(from_dt)
rescue
self.errors.add_to_base("invalid from dt")
end
end
我正在使用<%= f.error_messages %>
在表单上显示错误消息。
我使用from_dt作为虚拟属性(字符串)。表单上显示'存在'和'格式'验证错误,但是当用户在表单上输入无效的日期格式并且Date.Parse引发异常时,我在rescue子句中有'errors.add_to_base'语句。任何人都可以告诉我为什么当我禁用'格式'验证时,此错误不会出现在表单错误消息中。
感谢。
答案 0 :(得分:11)
运行验证时,将删除在验证回调之外添加的错误 - ActiveModel
因此,您必须在验证回调中添加错误,而不是在setter中添加。这应该有效:
class Mytimeperiod < ActiveRecord::Base
validates presence of :from_dt
validates_format_of :from_dt, :with => /\A\d{2}\/\d{2}\/\d{4}\Z/, :message => "format is mm/dd/yyyy"
validate :from_dt_must_parse
def from_dt
self.from_date.strftime("%m/%d/%Y") if !self.from_date.blank?
end
def from_dt=(from_dt)
self.from_date = Date.parse(from_dt)
rescue
@from_dt_parse_error = "not recognizable as a date"
end
def from_dt_must_parse
self.errors[:from_dt] = @from_dt_parse_error
end
end
答案 1 :(得分:0)
您的语法看起来不错。如果您在控制台中遇到问题,请务必执行reload!
(或再次退出并运行script/console
。)
如果您使用虚拟属性的唯一原因是验证日期格式,请不要忘记您可以使用validate
方法(未经测试)进行自己的验证:
class Mytimeperiod < ActiveRecord::Base
protected
def validate
date = Date.parse(from_date)
rescue
errors.add("from_date", "date is invalid")
end
end
这样做的好处是可以在字段而不是对象中添加错误。
答案 2 :(得分:-1)
我认为问题实际上只是您的语法,您需要开始在包含begin
的块的开头添加rescue
:
def from_dt=(from_dt)
begin
self.from_date = Date.parse(from_dt)
rescue
self.errors.add_to_base("invalid from dt")
end
end