Rails-Migrationen: Machen Sie die Standardeinstellung für eine Spalte rückgängig

190

Ich habe das Problem, dass ich eine Migration in Rails habe, die eine Standardeinstellung für eine Spalte festlegt, wie in diesem Beispiel:

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

Angenommen, ich möchte diese Standardeinstellungen in einer späteren Migration löschen. Wie mache ich das mit Rails-Migrationen?

Meine aktuelle Problemumgehung ist die Ausführung eines benutzerdefinierten SQL-Befehls in der Rails-Migration wie folgt:

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

Dieser Ansatz gefällt mir jedoch nicht, da ich jetzt davon abhängig bin, wie die zugrunde liegende Datenbank diesen Befehl interpretiert. Im Falle einer Änderung der Datenbank funktioniert diese Abfrage möglicherweise nicht mehr und die Migration wird unterbrochen. Gibt es eine Möglichkeit, das Rückgängigmachen einer Standardeinstellung für eine Spalte in Schienen auszudrücken?

Wulfovitch
quelle

Antworten:

387

Schienen 5+

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

Schienen 3 und Schienen 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
quelle
7
In Postgres wird dadurch die Standardeinstellung für CHARACTER VARYINGSpalten nicht gelöscht, sondern nur auf gesetzt NULL::character varying.
Attila O.
8
In neueren Versionen können Sie es reversibel machen. Zum Beispiel: change_column_default(:table_name, :column_name, from: nil, to: false)
Mark
1
@ AttilaO. Ich hatte Erfolg beim Laufen ALTER TABLE table_name ALTER COLUMN type DROP DEFAULT, NULLich glaube , ich muss es nicht einstellen .
Eli Rose - WIEDERHERSTELLEN MONICA
Zu Ihrer Information, es sieht so aus, als ob die reversible Version, die @ Mark erwähnt, in Rails 5+ hinzugefügt wurde. Alles, was darunter liegt, können Sie nicht verwenden.
Joshua Pinter
23

Klingt so, als würden Sie mit Ihrer 'Ausführung' das Richtige tun, wie in den Dokumenten hervorgehoben:

change_column_default(table_name, column_name, default)

Legt einen neuen Standardwert für eine Spalte fest. Wenn Sie den Standardwert auf NULL setzen möchten, haben Sie kein Glück. Sie müssen DatabaseStatements # die entsprechende SQL-Anweisung selbst ausführen. Beispiele

change_column_default(:suppliers, :qualification, 'new')
change_column_default(:accounts, :authorized, 1)
Serx
quelle
Vielen Dank! Ich habe diesen Hinweis selbst nicht in den Dokumenten gefunden! Hoffentlich bauen sie das Löschen von Standardwerten in Migrationen in zukünftigen Versionen von Rails ein.
Wulfovitch
1
Dies gilt ab Rails 3.1.0 nicht mehr, vgl. apidock.com/rails/v3.1.0/ActiveRecord/ConnectionAdapters/…
asymmetrisch
14

Das folgende Snippet verwende ich, um NULLSpalten zu erstellen NOT NULL, aber überspringe DEFAULTauf Schemaebene:

def self.up
  change_column :table, :column, :string, :null => false, :default => ""
  change_column_default(:table, :column, nil)
end
Alex Fortuna
quelle
Ich sehe in dieser Antwort keinen Mehrwert, da der akzeptierte den gleichen Wert angibt.
Mosselman
-3

Schienen 4

change_column :courses, :name, :string, limit: 100, null: false
Lesly Revenge
quelle
10
Dieser fügt NOT NULL Einschränkung hinzu, es hat nichts mit DEFAULT
Extrapolator
hat nichts mit STANDARD +1 zu tun
Ivan Wang