views:

47

answers:

1

Hello, I have run with a problem which i believe is Active Records fault. I am parsing an XML file which contains jobs. This xml file contains nodes which indicate walltime in the time format 00:00:00. I also have a model which will accept these jobs. However, when the time is larger than an actual 24H time, Active record inserts it as NULL. Examples below:

INSERT INTO `jobs` (`jobid`, `walltime`) VALUES('71413', 'NULL')

INSERT INTO `jobs` (`jobid`, `walltime`) VALUES('71413', '15:24:10')

Any ideas? Thank you!

+2  A: 

The standard SQL time and datetime data types aren't intended to store a duration. Probably in agreement with those standards, ActiveRecord's time attribute assignment logic uses the time parsing rules of the native Ruby Time class to reject invalid time of day.

The way to store durations, as you intend, is either:

  1. Store the duration as an integer (e.g. "number of seconds"), or
  2. Store two (date)times, a start and an end, and use date arithmetic on them.
class Thing < ActiveRecord::Base
  ...
  def duration
    return start - end
  end

  def duration=(length)
    start = Time.now
    end = start + length
  end
  ...
end
Andres Jaan Tack
This is not the case for MySQl (don't know about other implementations). See here: http://dev.mysql.com/doc/refman/5.0/en/time.html ("... values may range from '-838:59:59' to '838:59:59'. The hours part may be so large because the TIME type can be used not only to represent a time of day (which must be less than 24 hours), but also elapsed time or a time interval between two events (which may be much greater than 24 hours, or even negative).")
Milan Novota
Hi Milan - yes, MySql may well support duration-storage in a Time column - but because Active Record is intended to be cross-db compatible - it may still "helpfully" interpret the time as a clock-time-only. It therefore would continue nulling out anything that it sees as an "invalid time". Thus the duration option here is probably a better bet for ensuring that it will actually work.
Taryn East
@Taryn Per our suspicions, I found the code that does exactly that.
Andres Jaan Tack