I had a head slapper a while back where a Rails site I was working on wasn’t updating the created_at and updated_at fields properly in any of the tables.
(For those who don’t know, it’s a handy feature in ActiveRecord where these datetime columns get automatically refreshed on creates and saves – well, somewhat handy, until you over-rely on the updated_at field and then other business logic causes it to change when you don’t expect it, but I digress…)
Anyway, at the time I was working on a 3.0 beta rev, so I figured it was just something that was going to sort itself out, and I added some quick before_save and before_create handlers to the record to keep things in sync so I could work on the real problems (there were time and budget constraints and I was the only one who ever looked at those fields,) but I found it was still happening quite some time later on the official 3.0.x branch.
It turns out the problem was that these tables hadn’t been created through a standard Rails migration with a t.timestamps call; they’d been made up through a series of SQL scripts that had various explicit calls to create table.
And in there, the created_at field was defined as datetime not null default ’1900-01-01 00:00:00′.
Gotcha.
So here’s the lesson: if created_at has a default, Rails/ActiveRecord will use the default, just like it does for any other column in the db. You want these fields to be nullable without a default, so if this is happening to you, run a migration like this:
change_column :table_name, :created_at, :datetime, :null => true, :default => nil
Then you can get rid of embarrassing workarounds that shouldn’t have been there in the first place, especially since they now reflect a severe lack of understanding of how ActiveRecord works, at least compared to your newfound knowledge


{ 2 comments… read them below or add one }
Thanks! Been banging my head against the wall for the last couple of hours…
No problem David, I know that head banging feeling all too well!