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

Respuestas:


93

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

Pre-Rails 4, prueba change_column .


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

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

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.