wake-up-neo.com

Rails-Migration für Änderungsspalte

Wir haben script/generate migration add_fieldname_to_tablename fieldname:datatype-Syntax zum Hinzufügen neuer Spalten zu einem Modell.

Verfügen wir in derselben Zeile über ein Skript zum Generieren des Datentyps einer Spalte? Oder sollte ich SQL direkt in meine Vanilla-Migration schreiben?

Ich möchte eine Spalte von datetime in date ändern.

303
papdel

Ich denke das sollte funktionieren.

change_column :table_name, :column_name, :date
517
Alex Korban

Sie können einen Block auch verwenden, wenn Sie mehrere Spalten in einer Tabelle ändern möchten.

Beispiel:

change_table :table_name do |t|
  t.change :column_name, :column_type, {options}
end

Weitere Informationen finden Sie in der API-Dokumentation zur Table-Klasse .

96
John

Mir ist nicht bekannt, ob Sie eine Migration von der Befehlszeile aus erstellen können, aber Sie können eine neue Migration erstellen und dann die Migration bearbeiten, um diese Aufgaben auszuführen.

Wenn Tabellenname der Name Ihrer Tabelle ist, Feldname der Name Ihres Felds ist und Sie die Datums- und Datumsangabe in Datum ändern möchten, können Sie dazu eine Migration schreiben.

Sie können eine neue Migration erstellen mit:

Rails g migration change_data_type_for_fieldname

Bearbeiten Sie dann die Migration, um change_table zu verwenden:

class ChangeDataTypeForFieldname < ActiveRecord::Migration
  def self.up
    change_table :tablename do |t|
      t.change :fieldname, :date
    end
  end
  def self.down
    change_table :tablename do |t|
      t.change :fieldname, :datetime
    end
  end
end

Führen Sie dann die Migration aus:

rake db:migrate
84
Ryan

Wie ich in den vorherigen Antworten gefunden habe, sind drei Schritte erforderlich, um den Typ einer Spalte zu ändern:

Schritt 1:

Generieren Sie eine neue Migrationsdatei mit diesem Code:

Rails g migration sample_name_change_column_type

Schritt 2: 

Gehen Sie zum Ordner /db/migrate und bearbeiten Sie die von Ihnen erstellte Migrationsdatei. Es gibt zwei verschiedene Lösungen.

  1. def change
        change_column(:table_name, :column_name, :new_type)
    end
    

2.

    def up
        change_column :table_name, :column_name, :new_type
    end

    def down
        change_column :table_name, :column_name, :old_type
    end

Schritt 3:

Vergiss nicht diesen Befehl auszuführen:

rake db:migrate

Ich habe diese Lösung für Rails 4 getestet und funktioniert gut.

28
Aboozar Rajabi

Mit Schienen 5

Von Rails Guides :

Wenn Sie möchten, dass eine Migration etwas unternimmt, das Active Record nicht umkehren kann, können Sie reversible verwenden:

class ChangeTablenameFieldname < ActiveRecord::Migration[5.1]
  def change
    reversible do |dir|
      change_table :tablename do |t|
        dir.up   { t.change :fieldname, :date }
        dir.down { t.change :fieldname, :datetime }
      end
    end
  end
end
6
Mr. Tao

Einfach Migration generieren:

Rails g migration change_column_to_new_from_table_name

Aktualisieren Sie die Migration wie folgt:

class ClassName < ActiveRecord::Migration
    change_table :table_name do |t|
      t.change :column_name, :data_type
    end
end

und schlussendlich

rake db:migrate
6
Vivek Sharma

Eine andere Möglichkeit, den Datentyp mithilfe der Migration zu ändern

Schritt 1: Sie müssen den fehlerhaften Datentypfeldnamen mithilfe der Migration entfernen

Ex:

Rails g migration RemoveFieldNameFromTableName field_name:data_type

Vergessen Sie nicht, den Datentyp für Ihr Feld anzugeben

Schritt 2: Jetzt können Sie ein Feld mit dem richtigen Datentyp hinzufügen

Ex:

Rails g migration AddFieldNameToTableName field_name:data_type

Das ist es, jetzt wird Ihre Tabelle mit dem korrekten Datentypfeld Happy Ruby-Codierung hinzugefügt.

1
prasanthrubyist

Um die Antworten im Falle einer Bearbeitung zu vervollständigen Standardwert :

In Ihrer Rails-Konsole:

Rails g migration MigrationName

In der Migration:

  def change
    change_column :tables, :field_name, :field_type, default: value
  end

Wird aussehen wie :

  def change
    change_column :members, :approved, :boolean, default: true
  end
0
Gregdebrick

Dies setzt alles voraus, dass der Datentyp der Spalte eine implizite Konvertierung für vorhandene Daten hat. Ich bin in mehrere Situationen geraten, in denen die vorhandenen Daten, beispielsweise eine String, implizit in den neuen Datentyp konvertiert werden können, beispielsweise Date

In dieser Situation ist es hilfreich zu wissen, dass Sie Migrationen mit Datenkonvertierungen erstellen können. Ich persönlich mag es, diese in meine Modelldatei zu legen und sie dann zu entfernen, nachdem alle Datenbankschemas migriert wurden und stabil sind.

/app/models/table.rb
  ...
  def string_to_date
    update(new_date_field: date_field.to_date)
  end

  def date_to_string
    update(old_date_field: date_field.to_s)
  end
  ...
    def up
        # Add column to store converted data
        add_column :table_name, :new_date_field, :date
        # Update the all resources
        Table.all.each(&:string_to_date)
        # Remove old column
        remove_column :table_name, :date_field
        # Rename new column
        rename_column :table_name, :new_date_field, :date_field
    end

    # Reversed steps does allow for migration rollback
    def down
        add_column :table_name, :old_date_field, :string
        Table.all.each(&:date_to_string)
        remove_column :table_name, :date_field
        rename_column :table_name, :old_date_field, :date_field
    end
0