Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails set default DateTime to now

In my app I have teams and each team has a game time every week. I want the game times to be set to 'now' as a default. My table is set up like so

create_table "teams", force: true do |t|
  t.datetime "wk1_time"
end

I created a migration and it looks like this:

class ChangeDateTimeDefault < ActiveRecord::Migration
  def change
    change_column :teams, :wk1_time, :default => DateTime.now
  end
end

When I run rake db:migrate I get an error. Is my syntax wrong or am I missing something else?

like image 588
Phil Mok Avatar asked Jun 23 '15 03:06

Phil Mok


Video Answer


3 Answers

Since Rails 5 you can make a migration like this:

change_column_default :users, :wk1_time, -> { 'CURRENT_TIMESTAMP' }

In my mind this is the best option because it not database specific answer.

like image 101
alexandre-rousseau Avatar answered Oct 18 '22 00:10

alexandre-rousseau


Yes, you are missing the type :

class ChangeDateTimeDefault < ActiveRecord::Migration
  def change
    change_column :teams, :wk1_time, :datetime, :default => DateTime.now
  end
end

But, you need the below not the above one, because you just want to change the default.

class ChangeDateTimeDefault < ActiveRecord::Migration
  def change
    change_column_default :teams, :wk1_time, DateTime.now
  end
end

But none of these are correct approach for your task. The reason is DateTime.now will be evaluated based upon when you ran the migration, instead when the record is created. You need look to into this answer to know how to set the default time.

like image 45
Arup Rakshit Avatar answered Oct 18 '22 01:10

Arup Rakshit


EDIT: For Rails 5+ there are better answers, like this one: https://stackoverflow.com/a/55357711/252799, though the below still works.

The way I found, was to do a migration on an existing datetime column, like this:

#migration
execute("ALTER TABLE teams ALTER COLUMN wk1_time SET DEFAULT CURRENT_TIMESTAMP")

that produces a schema.rb entry shown like this:

#schema.rb
t.datetime "wk1_time",                    default: "now()", null: false

The "now()" is a string sent to postgresql and evaluated at runtime, upon each insert.

like image 8
oma Avatar answered Oct 18 '22 00:10

oma