在 Rails 迁移中,如何将列的默认值设置为 NOW() 而不是 运行 迁移时的时间?
In a Rails migraiton, how do I set the default value of a column to be NOW() instead of the time when I ran the migration?
我有一个 PostGres 9.4 数据库。我想将 DATETIME 列的默认列类型更改为创建记录的时间。我认为这是正确的方法,因为这是我的 rails 迁移
class ChangeDefaultValueForStratumWorkerSubmissions < ActiveRecord::Migration[5.1]
def change
change_column_default(:stratum_worker_submissions, :created_at, 'NOW')
end
end
但是当我查看我的数据库时,默认时间戳显示为我 运行 迁移的时间,而不是我想要的表达式。如何编写一个可以满足我要求的迁移?
Column | Type | Modifiers
-------------------+-----------------------------+----------------------------------------------------------------------------
id | integer | not null default nextval('stratum_worker_submissions_id_seq'::regclass)
stratum_worker_id | integer |
created_at | timestamp without time zone | not null default '2018-04-04 19:46:22.781613'::timestamp without time zone
它没有很好的记录,但您可以提供一个 lambda 作为迁移中的默认值,这将做正确的事情。如果你这样说:
def change
change_column_default :stratum_worker_submissions, :created_at, -> { 'now()' }
end
然后列的默认值将设置为 now()
并且在列需要默认值之前不会调用数据库函数 now()
。那么如果你在 psql
中 \d stratum_worker_submissions
你会看到:
created_at | timestamp without time zone | not null default now()
随心所欲。任何其他默认值都将在迁移运行时进行评估,您最终会得到一个固定的时间戳作为默认值。
或者,您始终可以使用 SQL:
手动完成
def up
connection.execute(%q(
alter table stratum_worker_submissions
alter column created_at
set default now()
))
end
def down
connection.execute(%q(
alter table stratum_worker_submissions
alter column created_at
drop default
))
end
请注意,如果您开始使用 SQL 手动更改架构,您可能会开始执行 db/schema.rb
中不会出现的操作,因为您可以快速进入 SQL 而 ActiveRecord 不会明白。如果发生这种情况,那么您可以通过更改 config/application.rb
:
从 db/schema.rb
更改为 db/structure.sql
config.active_record.schema_format = :sql
然后在修订控制中用 db/structure.sql
替换 db/schema.rb
并使用 db:structure
rake 任务代替通常的 db:schema
任务。
我有一个 PostGres 9.4 数据库。我想将 DATETIME 列的默认列类型更改为创建记录的时间。我认为这是正确的方法,因为这是我的 rails 迁移
class ChangeDefaultValueForStratumWorkerSubmissions < ActiveRecord::Migration[5.1]
def change
change_column_default(:stratum_worker_submissions, :created_at, 'NOW')
end
end
但是当我查看我的数据库时,默认时间戳显示为我 运行 迁移的时间,而不是我想要的表达式。如何编写一个可以满足我要求的迁移?
Column | Type | Modifiers
-------------------+-----------------------------+----------------------------------------------------------------------------
id | integer | not null default nextval('stratum_worker_submissions_id_seq'::regclass)
stratum_worker_id | integer |
created_at | timestamp without time zone | not null default '2018-04-04 19:46:22.781613'::timestamp without time zone
它没有很好的记录,但您可以提供一个 lambda 作为迁移中的默认值,这将做正确的事情。如果你这样说:
def change
change_column_default :stratum_worker_submissions, :created_at, -> { 'now()' }
end
然后列的默认值将设置为 now()
并且在列需要默认值之前不会调用数据库函数 now()
。那么如果你在 psql
中 \d stratum_worker_submissions
你会看到:
created_at | timestamp without time zone | not null default now()
随心所欲。任何其他默认值都将在迁移运行时进行评估,您最终会得到一个固定的时间戳作为默认值。
或者,您始终可以使用 SQL:
手动完成def up
connection.execute(%q(
alter table stratum_worker_submissions
alter column created_at
set default now()
))
end
def down
connection.execute(%q(
alter table stratum_worker_submissions
alter column created_at
drop default
))
end
请注意,如果您开始使用 SQL 手动更改架构,您可能会开始执行 db/schema.rb
中不会出现的操作,因为您可以快速进入 SQL 而 ActiveRecord 不会明白。如果发生这种情况,那么您可以通过更改 config/application.rb
:
db/schema.rb
更改为 db/structure.sql
config.active_record.schema_format = :sql
然后在修订控制中用 db/structure.sql
替换 db/schema.rb
并使用 db:structure
rake 任务代替通常的 db:schema
任务。