Rails ActiveRecord Timestamp in Epoch 而不是 DateTime 格式
Posted
技术标签:
【中文标题】Rails ActiveRecord Timestamp in Epoch 而不是 DateTime 格式【英文标题】:Rails ActiveRecord Timestamp in Epoch instead of DateTime Format 【发布时间】:2016-10-05 23:26:58 【问题描述】:需要以 Epoch 而不是 DateTime 格式存储 created_at 和 updated_at 时间戳。有没有办法改变默认行为,同时让 ORM 来维护时间戳。
当我使用 Rails Generator 生成模型时
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 的时间戳。
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 年以来的时间长)而不是 DateTime 存储时间戳。
谢谢
【问题讨论】:
您是否尝试在架构中将created_at
和 updated_at
列定义为 timestamp
列?
是的。但默认情况下它采用 sql 日期时间格式。但我想将其存储为 Epoch 而不是 DateTime
对不起,也许我不明白你所说的 Epoch 是什么意思。我以为您的意思是将列存储为自 1970 年以来的秒数,我猜,如果您将列定义为 timestamp
列,那么它可能会起作用。您能否详细说明您想要实现的目标?
更新了我的问题
【参考方案1】:
你没有指定使用的数据库,所以我在这里假设 mysql。事实证明,Rails 支持时间戳的所有日期/时间列变体:DATE
、TIME
、DATETIME
、TIMESTAMP
甚至 INTEGER
。有关这些类型之间差异的更多信息,请参阅MySQL docs,有关 Rails 如何理解它们的信息,请参阅this answer。
1) TIMESTAMP
时间戳列
如果您想将时间戳存储在TIMESTAMP
类型列中,请在迁移中尝试以下技巧(注意'timestamp '
中的空格,它是needed 否则Rails 将始终创建datetime
的列改为 - timestamp
只是 Rails 中 datetime
的别名):
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
s,从而为每条记录节省几个字节:
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
方法将日期时间转换为纪元以来的秒数:
Tenant.last.created_at.to_i
# => 1465375595
2) INTEGER
时间戳列
如果您确实想将时间戳存储为自纪元以来的秒数(1970),只需将时间戳列定义为INTEGER
类型列:
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 中也显示为整数:
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>
【讨论】:
以上是关于Rails ActiveRecord Timestamp in Epoch 而不是 DateTime 格式的主要内容,如果未能解决你的问题,请参考以下文章
Rails 3 包括翻译 globalize3 activerecord
Rails/Arel:选择所有记录作为 ActiveRecord::Relation