Migrazioni delle rotaie: annulla l'impostazione predefinita per una colonna


190

Ho il problema, che ho una migrazione in Rails che configura un'impostazione predefinita per una colonna, come questo esempio:

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

Supponiamo che mi piaccia abbandonare le impostazioni predefinite in una migrazione successiva, come posso fare con l'utilizzo delle migrazioni rails?

La mia attuale soluzione alternativa è l'esecuzione di un comando sql personalizzato nella migrazione delle rotaie, in questo modo:

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

Ma questo approccio non mi piace, perché ora dipendo da come il database sottostante sta interpretando questo comando. In caso di modifica del database, questa query potrebbe non funzionare più e la migrazione verrebbe interrotta. Quindi, c'è un modo per esprimere l'annullamento di un'impostazione predefinita per una colonna in rotaie?

Risposte:


387

Rotaie 5+

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

Rotaie 3 e Rotaie 4

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

def down
  change_column_default( :table_name, :column_name, false )
end

7
In Postgres, questo in realtà non eliminerà il valore predefinito per le CHARACTER VARYINGcolonne, ma semplicemente impostalo su NULL::character varying.
Attila O.

8
Nelle versioni più recenti, puoi renderlo reversibile. Ad esempio: change_column_default(:table_name, :column_name, from: nil, to: false)
Segna il

1
@AttilaO. Ho avuto successo correndo ALTER TABLE table_name ALTER COLUMN type DROP DEFAULT, non c'è bisogno di impostarlo su NULLcredo.
Eli Rose - REINSTATE MONICA

Cordiali saluti, sembra che la versione reversibile menzionata da @Mark sia stata aggiunta in Rails 5+, quindi qualsiasi cosa al di sotto di questa, non sarà possibile usarla.
Joshua Pinter

23

Sembra che tu stia facendo la cosa giusta con il tuo 'esegui', come indicano i documenti:

change_column_default(table_name, column_name, default)

Imposta un nuovo valore predefinito per una colonna. Se si desidera impostare il valore predefinito su NULL, si è sfortunati. È necessario DatabaseStatements # eseguire manualmente l'istruzione SQL appropriata. Esempi

change_column_default(:suppliers, :qualification, 'new')
change_column_default(:accounts, :authorized, 1)

Grazie! Non ho trovato questo suggerimento nei documenti da solo! Si spera che costruiscano il rilascio di valori predefiniti nelle migrazioni nelle versioni future delle rotaie.
wulfovitch,

1
Questo non è più vero a partire da Rails 3.1.0, cfr. apidock.com/rails/v3.1.0/ActiveRecord/ConnectionAdapters/…
asimmetrico

14

Il seguente frammento che uso per creare NULLcolonne NOT NULL, ma salta DEFAULTa livello di schema:

def self.up
  change_column :table, :column, :string, :null => false, :default => ""
  change_column_default(:table, :column, nil)
end

Non vedo valore aggiunto in questa risposta poiché quello accettato afferma lo stesso.
Mosselman,

-3

Rotaie 4

change_column :courses, :name, :string, limit: 100, null: false

10
Questo aggiunge il vincolo NOT NULL, non ha nulla a che fare con DEFAULT
Extrapolator

non ha nulla a che fare con DEFAULT +1
Ivan Wang del
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.