Reputation: 1793
Need to store created_at and updated_at timestamps in Epoch instead of DateTime Format. Is there a way to alter the default behaviour, while having ORM to do it's job to maintain the timestamp.
When I use Rails Generator to generate my models
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
Not the timestamp that translates to 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
I know that I can directly create two columns, and manually alter the created_at and updated_at fields everytime the record is added/changed, But that's going to be lots of bad code redundant code introduced in the application.
What I need is to somehow store the timestamps in epoch format (Time since 1970 in Long) instead of DateTime.
Thanks
Upvotes: 0
Views: 3148
Reputation: 15954
You have not specified the DB used, so I assume MySQL here. It turns out Rails supports all variants of date/time columns for the timestamps: DATE
, TIME
, DATETIME
, TIMESTAMP
and even INTEGER
. See the MySQL docs for more info about the differences between these types and this answer for info about how Rails understand them.
1) TIMESTAMP
timestamp columns
If you want to store the timestamps in TIMESTAMP
type columns, try the following trick in your migration (note the space in 'timestamp '
, it is needed otherwise Rails will always create the column as datetime
instead - timestamp
is only an alias for datetime
in Rails):
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
When working with the records, the timestamps will appear as a usual datetimes but will be stored as TIMESTAMP
s in the DB, thus saving a few bytes per record:
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">
Of course, you can always convert a datetime to seconds since the Epoch using the to_i
method:
Tenant.last.created_at.to_i
# => 1465375595
2) INTEGER
timestamp columns
If you want to store the timestamps indeed as seconds since the Epoch (1970), just define the timestamp columns as INTEGER
type columns:
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
Then, the timestamps in the records also appear as integers in 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>
Upvotes: 2