我有一个有氧运动模型,持续时间为#34;时间数据类型的字段(Rails 4.2.6 / Ruby 2.2.4应用程序)。我需要帮助对自定义验证器进行故障排除,以防止用户保存持续时间少于10分钟的有氧运动。
这是我的_form.html.erb中的相关字段:
<%= f.input :duration do %> <br>
<%= f.time_select :duration, :include_blank => true, include_seconds: true %>
<% end %>
这是我在/app/validators/duration_exceeds_ten_min_validator.rb中的自定义验证器
class DurationExceedsTenMinValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
unless duration_exceeds_ten_min
record.errors[attribute] << "must be at least 10 min"
end
end
private
# Check if duration is greater than or equal to 10 minutes, a.k.a. duration_exceeds_ten_min
# If that's the case, return true, otherwise false.
def duration_exceeds_ten_min
if Time.parse(self.duration.strftime("%H:%M:%S") < "00:10:00")
return false
else
return true
end
end
end
在我的cardio_exercise模型(cardio_exercise.rb)中,我补充说:
validates :duration, duration_exceeds_ten_min: true
代码执行时,会抛出以下错误:
undefined method `duration' for #<DurationExceedsTenMinValidator:0x0000000ef5c4c8>
当我&#34;强迫&#34;在真或假条件下,自定义验证器似乎正常工作。我的if语句有问题。我被卡住了;我无法弄清楚如何正确设置条件。如何修复自定义验证器?我感谢任何帮助&amp;咨询!
答案 0 :(得分:1)
只需将时间转换为秒,让ActiveSupport :: Duration完成工作。
def validate_each(record, attribute, value)
if value.to_i.seconds < 10.minutes
record.errors[attribute] << "must be at least 10 min"
end
end
如果您对您的方法无效的原因感兴趣,因为您在验证程序中使用self.duration
。在此上下文中self
是验证器 - 而不是模型。
答案 1 :(得分:0)
我的自定义验证程序的问题是由于我未能在time_select HTML中包含“ignore_date”选项。
在查看我的源代码时,我注意到日期值包含在用户输入的时间值中。由于这些“隐藏字段”,自定义验证器失败。 Ruby on Rails文档说明:“此方法[time_select]还将为实际的年,月和日生成3个输入隐藏标记,除非选项:ignore_date设置为true。”
在我的HTML中将选项“:ignore_date设置为true”后,我的自定义验证器按预期工作。 HTML中的这一变化解决了这个问题。用户不能再保存不到10分钟的有氧运动。我希望将来这对其他人来说是有用的信息。
我赞赏@max帮助我改进自定义验证器,并解释为什么验证器中“self”的位置与模型相比无效。