Migraciones de rieles: deshacer la configuración predeterminada para una columna

190

Tengo el problema, que tengo una migración en Rails que establece una configuración predeterminada para una columna, como este ejemplo:

def self.up
  add_column :column_name, :bought_at, :datetime, :default => Time.now
end

Supongamos que me gusta eliminar esa configuración predeterminada en una migración posterior, ¿cómo hago eso con el uso de migraciones de rieles?

Mi solución actual es la ejecución de un comando sql personalizado en la migración de rails, así:

def self.up
  execute 'alter table column_name alter bought_at drop default'
end

Pero no me gusta este enfoque, porque ahora dependo de cómo la base de datos subyacente está interpretando este comando. En caso de un cambio en la base de datos, esta consulta tal vez no funcione más y la migración se interrumpiría. Entonces, ¿hay alguna manera de expresar el deshacer de una configuración predeterminada para una columna en rieles?

wulfovitch
fuente

Respuestas:

387

Rieles 5+

def change
  change_column_default( :table_name, :column_name, from: nil, to: false )
end

Rieles 3 y Rieles 4

def up
  change_column_default( :table_name, :column_name, nil )
end

def down
  change_column_default( :table_name, :column_name, false )
end
Jeremy Mack
fuente
77
En postgres, esto en realidad no eliminará el valor predeterminado para las CHARACTER VARYINGcolumnas, solo configúrelo en NULL::character varying.
Atila O.
8
En versiones más recientes, puede hacerlo reversible. Por ejemplo: change_column_default(:table_name, :column_name, from: nil, to: false)
Marque
1
@AttilaO. He tenido éxito corriendo ALTER TABLE table_name ALTER COLUMN type DROP DEFAULT, no NULLcreo que sea ​​necesario configurarlo .
Eli Rose - REINSTATE MONICA
Para su información, parece que la versión reversible que menciona @Mark se agregó en Rails 5+, por lo que cualquier cosa debajo de eso, no podrá usarla.
Joshua Pinter el
23

Parece que estás haciendo lo correcto con tu 'ejecutar', como lo señalan los documentos:

change_column_default(table_name, column_name, default)

Establece un nuevo valor predeterminado para una columna. Si desea establecer el valor predeterminado en NULL, no tiene suerte. Necesita DatabaseStatements # ejecutar la declaración SQL apropiada usted mismo. Ejemplos

change_column_default(:suppliers, :qualification, 'new')
change_column_default(:accounts, :authorized, 1)
Serx
fuente
¡Gracias! ¡No he encontrado esta pista en los documentos por mí mismo! Esperemos que incorporen la caída de los valores predeterminados en las migraciones en futuras versiones de rails.
wulfovitch
1
Esto ya no es así a partir de Rails 3.1.0, cfr. apidock.com/rails/v3.1.0/ActiveRecord/ConnectionAdapters/…
asimétrico el
14

El siguiente fragmento que uso para hacer NULLcolumnas NOT NULL, pero omito DEFAULTa nivel de esquema:

def self.up
  change_column :table, :column, :string, :null => false, :default => ""
  change_column_default(:table, :column, nil)
end
Alex Fortuna
fuente
No veo valor agregado en esta respuesta ya que la aceptada dice lo mismo.
Mosselman
-3

Carriles 4

change_column :courses, :name, :string, limit: 100, null: false
Venganza lesly
fuente
10
Este agrega la restricción NOT NULL, no tiene nada que ver con DEFAULT
Extrapolator
no tiene nada que ver con DEFAULT +1
Ivan Wang