Ruby on Rails: Wie füge ich einer vorhandenen Spalte mithilfe einer Migration eine Nicht-Null-Einschränkung hinzu?

130

In meiner Rails (3.2) -App habe ich eine Reihe von Tabellen in meiner Datenbank, aber ich habe vergessen, einige nicht null Einschränkungen hinzuzufügen. Ich habe herum gegoogelt, aber ich kann nicht finden, wie eine Migration geschrieben wird, die einer vorhandenen Spalte nicht null hinzufügt.

TIA.

David Robertson
quelle

Antworten:

93

Für Rails 4+ die Antwort der Nates (mit change_column_null ) besser.

Pre-Rails 4, versuchen Sie change_column .

Dan Wich
quelle
25
Seien Sie bei diesem Ansatz vorsichtig. Wenn Sie andere Attribute für diese Spalte hatten (z. B. eine :limitEinschränkung), müssen Sie diese Attribute bei der Verwendung wiederholen, da change_columnsie sonst verloren gehen. Aus diesem Grund bevorzuge ichchange_column_null
Nathan Wallace
Beachten Sie, dass dies eine generiert, IrreversibleMigrationdie möglicherweise nicht Ihren Wünschen entspricht.
Nic Nilov
@NicNilov sprichst du über die Antwort ODER den Kommentar von Nathan Wallace?
Mark
@ Mark Ich habe über die Antwort gesprochen, sorry, dass ich nicht spezifisch genug bin.
Nic Nilov
@NicNilov no dw Ich dachte das, obwohl ich nur noch einmal überprüfen wollte :)
Mark
273

Sie können auch change_column_null verwenden :

change_column_null :table_name, :column_name, false
nates
quelle
8
Sauberste Antwort!
Josh Click
1
Ich musste es für eine Reihe von Spalten ändern und dies erfordert nicht die Angabe des Spaltentyps für jede Spalte, viel besser!
Dorian
1
Dies ist die bessere Antwort. In meiner Datenbank habe ich einer Spalte mit bereits vorhandenen Nullwerten eine Nullbedingung hinzugefügt. change_column würde diese Werte nicht aktualisieren. Gemäß der Dokumentation hat change_column_null einen optionalen vierten Wert, der der neue Wert für das Update ist.
Merovex
Danke dafür. Beste Antwort.
Ryan Rebo
1
interessanter Nebeneffekt .... Wenn Sie die Migration zurücksetzen, wird das Feld auf das Gegenteil gesetzt (false -> true). Wenn Sie also die Migration für mehrere Felder erstellen, um eine Null-Einschränkung hinzuzufügen, und einige Felder BEREITS eine Null-Einschränkung hatten, und dann die Migration zurücksetzen, wird die Null-Einschränkung aus jedem Feld entfernt, in dem sie bereits vorhanden war.
JPW
10

1) ZUERST: Spalte mit Standardwert hinzufügen

2) DANN: Standardwert entfernen

add_column :orders, :items, :integer, null: false, default: 0
change_column :orders, :items, :integer, default: nil
rndrfero
quelle
2
Dies ist die richtige Lösung, wenn Sie eine neue Spalte hinzufügen müssen, die nicht null ist. Sie müssen zuerst definieren, dass sie einen Standardwert hat, da SQLLite sich beschwert (eine NOT NULL-Spalte mit dem Standardwert NULL kann nicht hinzugefügt werden), und sie dann entfernen!
Mailand
2

Wenn Sie es für ein neues Migrationsskript / -schema zum Erstellen verwenden, können Sie es wie folgt definieren

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
quelle