ActiveRecord存储时间没有微秒精度?

时间:2013-10-03 18:09:36

标签: ruby-on-rails ruby activerecord ruby-on-rails-4

我已经创建了带有created_ord和updated_at列的表,用于activerecord自动填充这些字段。我使用rails 4和mariadb 5.5与mysql2 0.3.13 gem

`created_at` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
`updated_at` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,

但是当我保存项目时,精度不是(6)/微秒。就像

+----------------------------+----------------------------+
| created_at                 | updated_at                 |
+----------------------------+----------------------------+
| 2013-10-03 17:31:54.000000 | 2013-10-03 17:31:54.000000 |
| 2013-10-03 17:32:32.000000 | 2013-10-03 17:32:32.000000 |
| 2013-10-03 17:33:29.000000 | 2013-10-03 17:33:29.000000 |
| 2013-10-03 17:35:06.000000 | 2013-10-03 17:35:06.000000 |
| 2013-10-03 18:06:20.000000 | 2013-10-03 18:06:20.000000 |
+----------------------------+----------------------------+

如何强制activerecord使用微秒精度?

1 个答案:

答案 0 :(得分:1)

根据这篇SO帖子:

How to insert a microsecond-precision datetime into mysql?

5.6.4之前的MySQL在任何时间类型中都不支持微秒精度。因此,您似乎需要使用2列,将普通created_at称为datetime,其他created_at_usecint

像这样的东西。请注意,您需要一个访问器方法,将两个字段组合成一个以便于阅读:

module MicrosecondTimestamps
  extend ActiveSupport::Concern
  module ClassMethods
   # none right now
  end

  included do
    before_create :set_created_at
    before_save :set_updated_at

    attr_reader :updated_at, :created_at
  end

  private

  def set_created_at
    if created_at.blank?
      time = Time.now.utc
      self.write_attribute(:created_at, time)
      self.created_at_usec = time.usec
    end
  end

  def set_updated_at
    time = Time.now.utc
    self.write_attribute(:updated_at, time)
    self.updated_at_usec = time.usec
  end

  def created_at
    @created_at ||= begin
      coerced_time = attributes[:created_at].to_i
      Time.at(coerced_time, created_at_usec)
    end
  end

  def updated_at
    @updated_at ||= begin
      coerced_time = attributes[:updated_at].to_i
      Time.at(coerced_time, updated_at_usec)
    end
  end

end

然后您可以将它包含在所有需要它的模型中:

class Foo < ActiveRecord:Base
  include MicrosecondTimestamps
end