我在模型中有一个before_validation
。其目的是计算两个DateTime
对象之间的工作时间,并将该值插入time_worked
属性。它的成功取决于两个字段的有效性,它会吐出第三个字段的值,而第三个字段又有验证。
class TimeEntry < ActiveRecord::Base
validates :start_time, :end_time, :presence => true
validates :time_worked, :presence => true, :numericality => true
before_validation :calculate_time_worked
def calculate_time_worked
time_float = (Time.parse(self.end_time.to_s) - Time.parse(self.start_time.to_s)) / 1.hour
self.time_worked = ((time_float * 10).ceil).to_f/10
end
问题是如果calculate_time_worked
或start_time
为空或无效,我的end_time
方法将失败,这正是这两个字段验证的原因!
任何想法如何重构?
答案 0 :(得分:1)
来自@PedroMedeiros的before_save解决方案将在这种情况下工作....但是如果你想验证time_worked是肯定的,那么你可能会做这样的事情:
validate :calculate_time_worked
def calculate_time_worked
return if end_time.blank? || start_time.blank?
time_float = (Time.parse(self.end_time.to_s) - Time.parse(self.start_time.to_s)) / 1.hour
self.time_worked = ((time_float * 10).ceil).to_f/10
if time_worked < 0
self.errors.add(:end_time, "Must be after Start Time")
end
end
最后 - 这个问题在getting the difference of time in hours
上很酷答案 1 :(得分:0)
它确实在这些方法设置之前调用before_validates。如果我在哪里,我会使用before_save来计算_time_worked。一旦attrs设置好,你的验证就会完成。
class TimeEntry < ActiveRecord::Base
validates :start_time, :end_time, :presence => true
validates :time_worked, :presence => true, :numericality => true
before_save :calculate_time_worked
end