I am overriding an attribute accessor in ActiveRecord to convert a string in the format "hh:mm:ss" into seconds. Here is my code:
class Call < ActiveRecord::Base
attr_accessible :duration
def duration=(val)
begin
result = val.to_s.split(/:/)
.map { |t| Integer(t) }
.reverse
.zip([60**0, 60**1, 60**2])
.map { |i,j| i*j }
.inject(:+)
rescue ArgumentError
#TODO: How can I correctly report this error?
errors.add(:duration, "Duration #{val} is not valid.")
end
write_attribute(:duration, result)
end
validates :duration, :presence => true,
:numericality => { :greater_than_or_equal_to => 0 }
validate :duration_string_valid
def duration_string_valid
if !duration.is_valid? and duration_before_type_cast
errors.add(:duration, "Duration #{duration_before_type_cast} is not valid.")
end
end
end
I am trying to meaningfully report on this error during validation. The first two ideas that I have had are included in the code sample.
- Adding to errors inside of the accessor override - works but I am not certain if it is a nice solution.
- Using the validation method
duration_string_valid
. Check if the other validations failed and report on duration_before_type_cast. In this scenarioduration.is_valid?
is not a valid method and I am not certain how I can check that duration has passed the other validations. - I could set a instance variable inside of duration=(val) and report on it inside
duration_string_valid
.
I would love some feedback as to whether this is a good way to go about this operation, and how I could improve the error reporting.