views:

206

answers:

3

I have some code that simply accesses a datetime field so activerecord converts it to a Time object automatically when I read it:

@some_appointment.some_time

The problem is that sometimes the "some_time" datetime column has bad data. "0209-12-20" instead of "2009-12-20". This causes to Ruby to throw a "year too big to marshal" error just from accessing, and I can't seem to catch it as the error is not an exception. Given that there is some invalid data in my database, I want to try and make the time object myself by reading the datetime string and using Time.parse so I can catch an exception if the time cannot be parsed. How can I accomplish this? Is there a better way?

+3  A: 

You might try attribute_for_inspect, as in:

SomeModel.find(:first).attribute_for_inspect 'some_time'
#=> ""2009-02-23 23:15:24""

You might also consider just writing a stand-alone script that doesn't use activerecord to go over your data in the database to normalize it or something. That would probably be faster than coding the special-case of bad data into your app.

thenduks
+2  A: 

I haven't tested this to see if it works, but have you tried attributes_before_type_cast? It returns the data before Rails runs the type conversion, but I am not sure if Rails will try to do the conversion when it loads the objects anyways.

Example:

@some_appointment.attributes_before_type_cast['some_time']
ScottD
or better yet: `@some_appointment.some_time_before_type_cast`
Ben Marini
+1  A: 

You could override the default accessors like this in your model:

def some_time
  read_attribute(:some_time)
  rescue
    # Try to parse this guy
    self.some_time_before_type_cast
end
Ben Marini