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.
 
    