Rails将默认DateTime设置为now

plm*_*k61 4 ruby-on-rails

在我的应用程序中,我有团队,每个团队每周都有一个游戏时间.我希望将游戏时间设置为"现在"作为默认值.我的桌子是这样设置的

create_table "teams", force: true do |t|
  t.datetime "wk1_time"
end
Run Code Online (Sandbox Code Playgroud)

我创建了一个迁移,它看起来像这样:

class ChangeDateTimeDefault < ActiveRecord::Migration
  def change
    change_column :teams, :wk1_time, :default => DateTime.now
  end
edn
Run Code Online (Sandbox Code Playgroud)

当我运行rake db:migrate时出现错误.我的语法错了还是我错过了其他的东西?

Rou*_*dre 9

从 Rails 5 开始,您可以进行这样的迁移:

change_column_default :users, :wk1_time, -> { 'CURRENT_TIMESTAMP' }
Run Code Online (Sandbox Code Playgroud)

在我看来,这是最好的选择,因为它不是特定于数据库的答案。


Aru*_*hit 8

是的,你错过了类型:

class ChangeDateTimeDefault < ActiveRecord::Migration
  def change
    change_column :teams, :wk1_time, :datetime, :default => DateTime.now
  end
end
Run Code Online (Sandbox Code Playgroud)

但是,您需要以下而不是上面的那个,因为您只想更改默认值.

class ChangeDateTimeDefault < ActiveRecord::Migration
  def change
    change_column_default :teams, :wk1_time, DateTime.now
  end
end
Run Code Online (Sandbox Code Playgroud)

但这些都不是你的任务的正确方法.原因DateTime.now将根据您运行迁移的时间进行评估,而不是在创建记录时进行评估.您需要查看此答案以了解如何设置默认时间.


oma*_*oma 8

编辑:对于 Rails 5+ 有更好的答案,比如这个: https : //stackoverflow.com/a/55357711/252799,尽管下面仍然有效。

我发现的方法是对现有的日期时间列进行迁移,如下所示:

#migration
execute("ALTER TABLE teams ALTER COLUMN wk1_time SET DEFAULT CURRENT_TIMESTAMP")
Run Code Online (Sandbox Code Playgroud)

产生如下所示的 schema.rb 条目:

#schema.rb
t.datetime "wk1_time",                    default: "now()", null: false
Run Code Online (Sandbox Code Playgroud)

"now()"是发送到 postgresql 并在运行时评估的字符串,每次插入时。

  • 如果你投反对票,请告诉我为什么,这是一个教育论坛。我会尊重你,我知道我并不总是对的。此处介绍的解决方案对我们有用,只要我认为对其他人有帮助,我就不会拉它。 (2认同)
  • FWIW,至少在 Rails 6 上,这不起作用,因为它不在 lambda 中。为了使其工作,它需要是: `default: -&gt; { "now()" }` (2认同)