Answers:
Rails 5现在支持此功能。
这是一个示例迁移:
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
参见https://github.com/rails/rails/issues/27077上的讨论,并通过prathamesh-sonpatki回答
add_column :table_name, :start_date, :datetime, default: -> { 'CURRENT_TIMESTAMP' }
这就是schema.rb中看起来的样子,t.datetime "start_date", default: -> { "now()" }
但是当我创建新记录时,它并没有被填充。知道为什么吗?
post.reload
以获得这些值。它在这里解释:stackoverflow.com/questions/53804787/...
您可以在这样的模型中添加函数:
before_create :set_foo_to_now
def set_foo_to_now
self.foo = Time.now
end
这样,模型将在模型中设置当前时间。
您还可以在迁移中放置一些sql代码,以在数据库级别设置默认值,例如:
execute 'alter table foo alter column starts_at set default now()'
设置如下所示:
create_table :foo do |t|
t.datetime :starts_at, :null => false, :default => Time.now
end
导致在迁移过程中执行Time.now函数,因此将在数据库中创建表,如下所示:
create table foo ( starts_at timestamp not null default '2009-01-01 00:00:00');
但我认为这不是您想要的。
new()
)运行。因此self.foo = Time.now
将覆盖您可能提供的值new()
。我建议self.foo = Time.current unless self.foo.present?
改为。
:starts_at, :default => 'now()'
在schema.rb中放置一行。但是,当使用rake db:schema:dump
它将覆盖schema.rb :starts_at, :default => '2015-05-29 09:46:33'
(或启动脚本的任何日期)时,这将无法正常工作……可悲....
如果表具有名为的字段,则Active Record会自动为创建和更新操作添加时间戳记
created_at
/created_on
或updated_at
/的updated_on
。来源-api.rubyonrails.org
除了拥有该列之外,您无需执行任何其他操作。
我正在寻找类似的解决方案,但最终使用https://github.com/FooBarWidget/default_value_for。
该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
我通常这样做:
def change
execute("
ALTER TABLE your_table
ALTER COLUMN your_column
SET DEFAULT CURRENT_TIMESTAMP
")
end
因此,您schema.rb
将拥有类似以下内容:
create_table "your_table", force: :cascade do |t|
t.datetime "your_column", default: "now()"
end
rake db:migrate
,而在您使用加载架构文件时则无效rake db:schema:load
。
如果你需要改变 Rails 5中的现有DateTime列(而不是按照其他答案中的说明创建新表),以便可以利用默认日期功能,则可以创建如下迁移:
class MakeStartsAtDefaultDateForFoo < ActiveRecord::Migration[5.0]
def change
change_column :foos, :starts_at, :datetime, default: -> { 'CURRENT_TIMESTAMP' }
end
end
在@szymon-lipiński(SzymonLipiński)给出的答案中,execute方法对我不起作用。它抛出了MySQL语法错误。
对我有用的MySQL语法是这个。
execute "ALTER TABLE mytable CHANGE `column_name` `column_name` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP"
因此,可以按照以下步骤为迁移脚本中的datetime列设置默认值:
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
CURRENT_TIMESTAMP
中将是当前事务开始的时间,因此在同一事务中创建的多个记录将获得相同的值。如果您希望语句执行的当前当前时间(忽略事务上下文),请签出CLOCK_TIMESTAMP
。