Ruby on Rails: ¿cómo agrego una restricción no nula a una columna existente mediante una migración?

130

En mi aplicación Rails (3.2), tengo un montón de tablas en mi base de datos, pero olvidé agregar algunas restricciones no nulas. Busqué en Google pero no puedo encontrar cómo escribir una migración que agrega no nulo a una columna existente.

TIA

David Robertson
fuente

Respuestas:

93

Para Rails 4+, la respuesta de nates (usando change_column_null ) es mejor.

Pre-Rails 4, prueba change_column .

Dan Wich
fuente
25
Tenga cuidado con este enfoque: si tenía otros atributos sobre esa columna (por ejemplo, una :limitrestricción), debe repetir esos atributos al usarlos change_column, o se perderán. Por esta razón, prefiero usarchange_column_null
Nathan Wallace
Tenga en cuenta que esto genera un IrreversibleMigrationque puede no ser lo que desea.
Nic Nilov
@NicNilov, ¿estás hablando de la respuesta O del comentario de Nathan Wallace?
Mark
@ Mark Estaba hablando de la respuesta, perdón por no ser lo suficientemente específico.
Nic Nilov
@NicNilov no dw Pensé que, aunque solo quería comprobarlo dos veces :)
Marque el
274

También puede usar change_column_null :

change_column_null :table_name, :column_name, false
nates
fuente
8
Respuesta más limpia!
Josh Click
1
Tuve que cambiarlo por un montón de columnas y esto no requiere especificar el tipo de columna para cada columna, ¡mucho mejor!
Dorian
1
Esta es la mejor respuesta. En mi base de datos, estaba agregando una restricción nula en una columna con valores nulos preexistentes. change_column no actualizaría esos valores. Según la documentación, change_column_null tiene un cuarto valor opcional que es el nuevo valor para la actualización.
Merovex
Gracias por esto. La mejor respuesta.
Ryan Rebo
1
efecto secundario interesante ... revertir la migración establecerá el campo al contrario (falso -> verdadero). Por lo tanto, si crea la migración para varios campos para agregar una restricción nula, y algunos campos YA tenían una restricción nula, luego revierta la migración, ELIMINARÁ la restricción nula de cualquier campo que ya la tuviera.
jpw
10

1) PRIMERO: Agregar columna con valor predeterminado

2) ENTONCES: eliminar el valor predeterminado

add_column :orders, :items, :integer, null: false, default: 0
change_column :orders, :items, :integer, default: nil
rndrfero
fuente
2
esta es la solución correcta cuando necesita agregar una nueva columna que no es nula, primero debe definir que tiene un valor predeterminado porque SQLLite se quejará (¡No puede agregar una columna NO NULL con el valor predeterminado NULL) y luego eliminarla!
Milán
2

Si lo está utilizando en un nuevo script / esquema de creación de migración, aquí es cómo podemos definirlo

class CreateUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
    t.string :name, null: false     # Notice here, NOT NULL definition
    t.string :email, null: false
    t.string :password, null: false
    t.integer :created_by
    t.integer :updated_by 

    t.datetime :created_at
    t.datetime :updated_at, default: -> { 'CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP' }
   end
  end
end
Manjunath Reddy
fuente