Ruby on Rails: come posso aggiungere un vincolo non nullo a una colonna esistente usando una migrazione?


130

Nella mia app Rails (3.2), ho un sacco di tabelle nel mio database ma ho dimenticato di aggiungere alcuni vincoli non nulli. Ho cercato su Google ma non riesco a trovare come scrivere una migrazione che non aggiunge nulla a una colonna esistente.

TIA.

Risposte:


93

Per Rails 4+, la risposta di Nates (usando change_column_null ) è migliore.

Pre-Rails 4, prova change_column .


25
Fai attenzione con questo approccio: se avevi altri attributi su quella colonna (ad esempio un :limitvincolo), devi ripetere quegli attributi quando li usi change_column, altrimenti andranno persi. Per questo motivo, preferisco usarechange_column_null
Nathan Wallace il

Nota che questo genera un valore IrreversibleMigrationche potrebbe non essere quello che desideri.
Nic Nilov,

@NicNilov stai parlando della risposta O del commento di Nathan Wallace?
Segna il

@Mark Stavo parlando della risposta, scusami per non essere abbastanza specifico.
Nic Nilov,

@NicNilov no dw pensavo che anche se volevo solo ricontrollare :)
Mark,

274

Puoi anche usare change_column_null :

change_column_null :table_name, :column_name, false

8
Risposta più pulita!
Josh Click

1
Ho dovuto cambiarlo per un mucchio di colonne e questo non richiede di specificare il tipo di colonna per ogni colonna, molto meglio!
Dorian,

1
Questa è la risposta migliore Nel mio database, stavo aggiungendo un vincolo null su una colonna con valori null preesistenti. change_column non aggiorna questi valori. Secondo la documentazione, change_column_null ha un quarto valore opzionale che è il nuovo valore per l'aggiornamento.
Merovex,

Grazie per questo. Migliore risposta.
Ryan Rebo

1
interessante effetto collaterale .... il rollback della migrazione imposterà il campo al contrario (false -> true). Pertanto, se si crea la migrazione per diversi campi per aggiungere un vincolo nullo e alcuni campi hanno già avuto un vincolo nullo, quindi ripristinare la migrazione, RIMUOVERÀ il vincolo nullo da qualsiasi campo che lo avesse già.
jpw,

10

1) PRIMO: aggiungi colonna con valore predefinito

2) POI: rimuovere il valore predefinito

add_column :orders, :items, :integer, null: false, default: 0
change_column :orders, :items, :integer, default: nil

2
questa è la soluzione corretta quando è necessario aggiungere una nuova colonna che non è nulla, è necessario innanzitutto definire che ha un valore predefinito poiché SQLLite si lamenterà (Impossibile aggiungere una colonna NOT NULL con valore predefinito NULL), quindi rimuoverlo!
Milano,

2

Se lo stai utilizzando su un nuovo script / schema di migrazione creato, ecco come possiamo 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.