Rails ActiveRecord Epoch中的时间戳而不是DateTime格式

Rails ActiveRecord Timestamp in Epoch instead of DateTime Format

需要在Epoch中存储created_at和updated_at时间戳而不是DateTime格式。 有没有办法改变默认行为,同时让ORM完成维护时间戳的工作。

当我使用Rails Generator生成我的模型时

1
2
3
4
5
6
7
8
9
10
11
12
13
class CreateTenants < ActiveRecord::Migration[5.0]
  def change
    create_table :tenants do |t|
      t.string :tenant_name
      t.string :tenant_owner_name
      t.string :tenant_address
      t.string :tenant_email
      t.integer :pincode

      t.timestamps
    end
  end
end

不是转换为DateTime的时间戳。

1
2
3
4
5
6
7
8
9
create_table"tenants", force: :cascade, options:"ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.string  "tenant_name"
    t.string  "tenant_owner_name"
    t.string  "tenant_address"
    t.string  "tenant_email"
    t.integer "pincode"
    t.datetime"created_at",        null: false
    t.datetime"updated_at",        null: false
  end

我知道我可以直接创建两列,并在每次添加/更改记录时手动更改created_at和updated_at字段,但这将是应用程序中引入的大量错误代码冗余代码。

我需要的是以某种方式将时间戳以时期格式(自1970年以来的时间为Long)存储而不是DateTime。

谢谢


你没有指定使用的数据库,所以我在这里假设MySQL。事实证明,Rails支持时间戳的所有日期/时间列变体:DATETIMEDATETIMETIMESTAMP甚至INTEGER。有关这些类型之间的差异的更多信息,请参阅MySQL文档,以及有关Rails如何理解它们的信息的答案。

1)TIMESTAMP时间戳列

如果要将时间戳存储在TIMESTAMP类型列中,请在迁移中尝试以下技巧(注意'timestamp '中的空格,否则需要它,否则Rails将始终将列创建为DATETIME - TIMESTAMP是只有Rails中DATETIME的别名):

1
2
3
4
5
6
7
create_table :tenants do |t|
  # ...

  #t.timestamps (remove the default timestamps definition)
  t.column :created_at, 'timestamp ', null: false
  t.column :updated_at, 'timestamp ', null: false
end

处理记录时,时间戳将显示为通常的日期时间,但将作为TIMESTAMP存储在数据库中,从而为每条记录节省几个字节:

1
2
3
Tenant.create!
# => SQL (0.1ms)  INSERT INTO `tenants` (`created_at`, `updated_at`) VALUES ('2016-06-08 08:45:20', '2016-06-08 08:45:20')
=> #<Tenant id: 1, tenant_name: nil, tenant_owner_name: nil, tenant_address: nil, tenant_email: nil, pincode: nil, created_at:"2016-06-08 08:45:20", updated_at:"2016-06-08 08:45:20">

当然,您可以使用to_i方法将日期时间转换为自Epoch以来的秒数:

1
2
Tenant.last.created_at.to_i
# => 1465375595

2)INTEGER时间戳列

如果要将时间戳确实存储为自Epoch(1970)以来的秒数,只需将时间戳列定义为INTEGER类型列:

1
2
3
4
5
6
7
create_table :tenants do |t|
  # ...

  #t.timestamps (remove the default timestamps definition)
  t.integer :created_at, null: false
  t.integer :updated_at, null: false
end

然后,记录中的时间戳也在Rails中显示为整数:

1
2
3
Tenant.create!
# => SQL (0.2ms)  INSERT INTO `tenants` (`created_at`, `updated_at`) VALUES (1465375595, 1465375595)
# => #<Tenant id: 1, tenant_name: nil, tenant_owner_name: nil, tenant_address: nil, tenant_email: nil, pincode: nil, created_at: 1465375595, updated_at: 1465375595>