Ruby-on-rails 如何为日期时间列设置默认值以记录迁移中的创建时间?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1580805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to set a default value for a datetime column to record creation time in a migration?
提问by Harish Shetty
Consider the table creation script below:
考虑下面的表创建脚本:
create_table :foo do |t|
t.datetime :starts_at, :null => false
end
Is it's possible to set the default value as the current time?
是否可以将默认值设置为当前时间?
I am trying to find a DB independent equivalent in rails for the SQL column definitions given below:
我正在尝试为下面给出的 SQL 列定义在 rails 中找到一个独立于数据库的等效项:
Oracle Syntax
甲骨文语法
start_at DATE DEFAULT SYSDATE()
MySQL Syntax
MySQL 语法
start_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
OR
或者
start_at DATETIME DEFAULT NOW()
回答by Will
This is supported now in Rails 5.
这在 Rails 5 中现在得到支持。
Here is a sample migration:
这是一个示例迁移:
class CreatePosts < ActiveRecord::Migration[5.0]
def change
create_table :posts do |t|
t.datetime :modified_at, default: -> { 'CURRENT_TIMESTAMP' }
t.timestamps
end
end
end
See discussion at https://github.com/rails/rails/issues/27077and answer there by prathamesh-sonpatki
请参阅https://github.com/rails/rails/issues/27077 上的讨论,并由 prathamesh-sonpatki 回答
回答by Szymon Lipiński
You can add a function in a model like this:
您可以在模型中添加一个函数,如下所示:
before_create :set_foo_to_now
def set_foo_to_now
self.foo = Time.now
end
So that the model will set the current time in the model.
这样模型就会在模型中设置当前时间。
You can also place some sql code in the migration for setting the default value at the database level, something like:
您还可以在迁移中放置一些 sql 代码以在数据库级别设置默认值,例如:
execute 'alter table foo alter column starts_at set default now()'
Setting something like this:
设置如下:
create_table :foo do |t|
t.datetime :starts_at, :null => false, :default => Time.now
end
causes executing the Time.now function during migrating so then the table in database is created like this:
导致在迁移期间执行 Time.now 函数,因此数据库中的表是这样创建的:
create table foo ( starts_at timestamp not null default '2009-01-01 00:00:00');
but I think that it is not what you want.
但我认为这不是你想要的。
回答by Jim
Active Record automatically timestamps create and update operations if the table has fields named
created_at/created_onorupdated_at/updated_on. Source - api.rubyonrails.org
如果表具有名为
created_at/created_on或updated_at/ 的字段,则 Active Record 会自动为创建和更新操作添加时间戳updated_on。来源 - api.rubyonrails.org
You don't need to do anything else except to have that column.
除了拥有该列之外,您无需执行任何其他操作。
回答by Giovanni Cappellotto
I was searching for a similar solutions but I ended using https://github.com/FooBarWidget/default_value_for.
我正在寻找类似的解决方案,但我最终使用了https://github.com/FooBarWidget/default_value_for。
The default_value_forplugin allows one to define default values for ActiveRecord models in a declarative manner. For example:
该default_value_for插件允许以声明方式为 ActiveRecord 模型定义默认值。例如:
class User < ActiveRecord::Base
default_value_for :name, "(no name)"
default_value_for :last_seen do
Time.now
end
end
u = User.new
u.name # => "(no name)"
u.last_seen # => Mon Sep 22 17:28:38 +0200 2008
回答by Arturo Herrero
I usually do:
我通常这样做:
def change
execute("
ALTER TABLE your_table
ALTER COLUMN your_column
SET DEFAULT CURRENT_TIMESTAMP
")
end
So, your schema.rbis going to have something like:
所以,你schema.rb将有类似的东西:
create_table "your_table", force: :cascade do |t|
t.datetime "your_column", default: "now()"
end
回答by Matt Long
If you need to changean existing DateTime columnin Rails 5 (rather than creating a new table as specified in other answers) so that it can take advantage of the default date capability, you can create a migration like this:
如果您需要更改的现有DateTime列在导轨5(而不是在其他的答案中指定创建新表),以便它可以采取默认的日期能力的优势,你可以创建一个这样的迁移:
class MakeStartsAtDefaultDateForFoo < ActiveRecord::Migration[5.0]
def change
change_column :foos, :starts_at, :datetime, default: -> { 'CURRENT_TIMESTAMP' }
end
end
回答by Sony Mathew
In the answer given by @szymon-lipiński (Szymon Lipiński), the execute method didn't work for me. It was throwing a MySQL syntax error.
在@szymon-lipiński (Szymon Lipiński) 给出的答案中,execute 方法对我不起作用。它抛出了一个 MySQL 语法错误。
The MySQL syntax which worked for me is this.
对我有用的 MySQL 语法是这样的。
execute "ALTER TABLE mytable CHANGE `column_name` `column_name` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP"
So to set the default value for a datetime column in migration script can be done as follows:
因此,要在迁移脚本中为日期时间列设置默认值,可以按如下方式完成:
def up
create_table :foo do |t|
t.datetime :starts_at, :null => false
end
execute "ALTER TABLE `foo` CHANGE `starts_at` `starts_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP"
end

