开发者

Ruby on Rails: updated_at - set as 0 on creation

When I create a new record on query table, I want updat开发者_StackOverflowed_at (timestamp) to be '0000-00-00 00:00:00' - and not the current timestamp, as Ruby on Rails sets by default.

MySQL field:

`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP

However, Ruby on Rails generates this sql query:

INSERT INTO `queries` (`updated_at`) VALUES ('2011-01-04 17:40:15')

How do I fix this?


Rails sets updated_at to the current time because, well, thats when the record was most recently updated. It sees an update as a creation. If you want to check if something has ever been updated, check to see if its updated_at and created_at are the same.

Otherwise, you should be able to change the value inserted by forcing the attribute upon insertion.

Post.new(@params.merge({:updated_at => DateTime::new})

or, in a before_create method on your model, set self.updated_at = DateTime::new.


If you want Rails to skip recording the timestamps, you can utilize this API:

ActiveRecord::Base.record_timestamps = false
# This also works on individual models
Post.record_timestamps = false

Since Rails (ActiveRecord more appropriately) will not assign a value to this field, your DB will assign the default value to those fields.


I recently discovered this blog post on the subject.

To summarize, he describes (with examples) methods for overriding ActiveRecord's default behavior with these timestamp columns. He explains that ActiveRecord actually ignores provided updated_at information and always uses its own timestamps.

Ultimately, he monkey patches ActiveRecord to provide a new update_without_timestamping method that does the work of disabling and re-enabling timestamping and it's thread safe and only modifies the behavior of the model being worked on.

If you don't want to read the article, his final monkey patched code is as follows:

module ActiveRecord
  class Base

    def update_record_without_timestamping
      class << self
        def record_timestamps; false; end
      end

      save!

      class << self
        remove_method :record_timestamps
      end
    end

  end
end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜