Don’t Do That

So… maybe you are coding up your totally way rad awesome application in Rails — and you are thinking to yourself.

“Self, I really would like to set my own created_at and updated_at timestamps. Look — there’s even a way to do that in the Rails documentation

class Feed < ActiveRecord::Base self.record_timestamps = false # … end

At this point you need to back away from the keyboard. Quickly. If you don’t, pretty soon, somewhere in your application — you are going to run into this error:

Mysql::Error: Column ‘created_at’ cannot be null

Or ALL KINDS OF OTHER FUN SIDE EFFECTS (FUN is actually a euphemism here for various four letter words)

See, record_timestamps is a class variable for ActiveRecord::Base created with the rails :cattr_accessor — maybe the self.record_timestamps should have tipped us all off — maybe not (there’s also a class_inheritable_accessor — I’m not sure where all that gets used though)

Even experienced developers not all that fluent in ruby minutiae (I think class variables count as minutiae) cut-and-paste first and figure out how it works second (yeah, don’t do that either).

So — anyway — once you change record_timestamps once — you change it for all descendants of ActiveRecord::Base

There’s a bit of discussion this on a separate, but related problem at Evan Weaver’s blog (pay special attention to that threading issue for those playing along with the home game). And of course, your friendly neighborhood reminder of what happens with class variables at Nic Williams’ blog (I recommend reading that twice and breaking out the home game version of irb)

So the moral of the story? self.record_timestamps — Don’t Do That.

p.s. Production of this blog entry was made possible through various grants and assessments, and with some moans, groans, sighs, and “what tha–?” from my colleagues James Robinson and Aaron Hundley (doesn’t have a blog, he needs to get with the program) 🙂

p.p.s edited to change “you chance it for all descendants…” to “you change it for all descendants” — I think the first one is quite apropos however