ActiveRecord’s automatically updating created_at and updated_at timestamps are certainly a great feature. Every once in a while though they can bite you in the butt.
For example, let’s say you have a query that finds all the recently updated blog posts:
Post.all :order=>'updated_at DESC', :limit=>5
That code works great and has been in production for a long time. Then one day you decide to change the title of a blog post your wrote last year.
Post.find(123).update_attributes! :title=>"My New Title"
What’s the problem? All of a sudden this old post shows up as one of your recently updated blog posts on your site’s homepage! Uh oh. That’s probably not what you meant to happen. (At this point you realize that a “published_at” timestamp would have been useful, but hey, you didn’t write the original code.)
So how can you change the contents without changing the updated_at timestamp? One way is to skip ActiveRecord and run the query in the database; that certainly works but isn’t an ideal practice.
ActiveRecord comes with a flag that lets you turn timestamp setting on and off:
Post.record_timestamps = false
You can now safely change the title and the updated_at timestamp won’t change. You can even wrap it up inside a little function if you want:
def without_timestamps(*models, &block)
models.each{|m| m.record_timestamps = false }
begin
yield
ensure
models.each{|m| m.record_timestamps = true }
end
end
Then you can use it like so:
without_timestamps(Post,Comment) do
Post.find(123).update_attributes! :title=>"My New Title"
end