-
Notifications
You must be signed in to change notification settings - Fork 22.2k
Description
PostgreSQL allows columns to have functional defaults, but Rails does not appear to support this when using the migrations API. The most notorious example of this is outlined below:
CREATE TABLE a ( t1 TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP ); -- works
CREATE TABLE b ( t1 TIMESTAMPTZ DEFAULT NOW() ); -- works
CREATE TABLE c ( t1 TIMESTAMPTZ DEFAULT 'NOW()' ); -- fails and uses a static timestampTables A and B defined above will work as expected, allowing any new rows to have a proper default value that is calculated at the time of insert. Table C, however, will convert the string 'now' to the current time when the table is defined, causing all inserted default values to reflect the static timestamp instead.
When attempting to use the migration API, one might write code such as:
create_table :c do |t|
t.timestamp default: 'NOW()'
endThis unfortunately yields the broken use-case of table C from the SQL above.
Proposed Solution
To ensure backwards-compatibility, database portability, and coverage of cases not listed here, I propose adding an option such as raw_default that could be used to pass unquoted defaults to the database in the DDL of a migration.
create_table :c do |t|
t.timestamp raw_default: 'NOW()'
endWhich would yield the following DDL:
CREATE TABLE c ( t1 TIMESTAMPTZ DEFAULT NOW() );