439 Stimmen

Wie schreibt man eine Migration zum Umbenennen eines ActiveRecord-Modells und seiner Tabelle in Rails?

Ich bin schrecklich bei der Benennung und erkennen, dass es eine bessere Reihe von Namen für meine Modelle in meinem Rails app.
Gibt es eine Möglichkeit, ein Modell und die dazugehörige Tabelle mithilfe einer Migration umzubenennen?

619voto

readonly Punkte 323452

Hier ist ein Beispiel:

class RenameOldTableToNewTable < ActiveRecord::Migration
  def self.up
    rename_table :old_table_name, :new_table_name
  end

  def self.down
    rename_table :new_table_name, :old_table_name
  end
end

Ich musste die Modelldeklarationsdatei manuell umbenennen.

Bearbeiten:

In Rails 3.1 & 4, ActiveRecord::Migration::CommandRecorder weiß, wie man rename_table-Migrationen rückgängig machen kann, so dass Sie dies tun können:

class RenameOldTableToNewTable < ActiveRecord::Migration
  def change
    rename_table :old_table_name, :new_table_name
  end 
end

(Sie müssen Ihre Dateien immer noch manuell umbenennen).

77voto

bfcoder Punkte 2932

In Rails 4 war alles, was ich tun musste, die def-Änderung

def change
  rename_table :old_table_name, :new_table_name
end

Und alle meine Indizes wurden für mich übernommen. Ich brauchte die Indizes nicht manuell zu aktualisieren, indem ich die alten entfernte und neue hinzufügte.

Und auch bei den Indizes funktioniert es mit der Veränderung nach oben oder unten.

59voto

armchairdj Punkte 990

Die anderen Antworten und Kommentare betrafen die Umbenennung von Tabellen und Dateien sowie das Durchsuchen Ihres Codes.

Ich möchte noch ein paar Vorbehalte anbringen:

Nehmen wir ein Beispiel aus der Praxis, mit dem ich heute konfrontiert wurde: die Umbenennung eines Modells von "Merchant" in "Business".

  • Vergessen Sie nicht, die Namen der abhängigen Tabellen und Modelle in der gleichen Migration zu ändern. Ich habe meine Modelle Merchant und MerchantStat gleichzeitig in Business und BusinessStat geändert. Sonst hätte ich beim Suchen und Ersetzen viel zu viel auswählen müssen.
  • Für alle anderen Modelle, die über Fremdschlüssel von Ihrem Modell abhängen, werden die Spaltennamen der Fremdschlüssel in den anderen Tabellen von Ihrem ursprünglichen Modellnamen abgeleitet. Sie müssen also auch einige rename_column-Aufrufe für diese abhängigen Modelle durchführen. So musste ich beispielsweise die Spalte "merchant_id" in verschiedenen Join-Tabellen (für die has_and_belongs_to_many-Beziehung) und anderen abhängigen Tabellen (für normale has_one- und has_many-Beziehungen) in "business_id" umbenennen. Andernfalls hätte ich am Ende Spalten wie "business_stat.merchant_id", die auf "business.id" verweisen, gehabt. Hier ist eine gute Antwort auf die Frage, wie man Spalten umbenennt.
  • Denken Sie daran, bei der Suche nach Singular, Plural und Großbuchstaben zu suchen, Kleinbuchstaben und sogar GROSSBUCHSTABEN (die in Kommentaren vorkommen können) Ihrer Zeichenketten.
  • Am besten ist es, zuerst nach Pluralversionen zu suchen, dann nach Singularversionen. Das Wenn Sie einen unregelmäßigen Plural haben - wie in meinem Beispiel mit den Händlern :: Geschäfte - können Sie alle unregelmäßigen Plurale korrekt ermitteln. Andernfalls kann es vorkommen, dass Sie z. B. 'businesss' (3 s) als Zwischenzustand, was zu noch mehr Suchen und Ersetzen führt.
  • Ersetzen Sie nicht blindlings jedes Vorkommen. Wenn Ihre Modellnamen mit mit gängigen Programmierbegriffen, mit Werten in anderen Modellen oder mit Textinhalten in Ihren Ansichten kollidieren, könnten Sie am Ende zu eifrig sein. In meinem Beispiel wollte ich meinen Modellnamen in "Business" ändern, aber aber im Inhalt meiner Benutzeroberfläche immer noch als "Händler" bezeichnen. Ich hatte auch eine "Händler"-Rolle für meine Benutzer in CanCan - es war die Verwirrung zwischen der Händler-Rolle und dem Händler-Modell, die mich dazu veranlasste, das Modell überhaupt umzubenennen.

29voto

Rimian Punkte 34365

Sie müssen auch Ihre Indizes ersetzen:

class RenameOldTableToNewTable< ActiveRecord:Migration
  def self.up
    remove_index :old_table_name, :column_name
    rename_table :old_table_name, :new_table_name
    add_index :new_table_name, :column_name
  end 

  def self.down
    remove_index :new_table_name, :column_name
    rename_table :new_table_name, :old_table_name
    add_index :old_table_name, :column_name
  end
end

Und benennen Sie Ihre Dateien usw. manuell um, wie in anderen Antworten hier beschrieben.

Siehe: http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

Stellen Sie sicher, dass Sie nach dem Schreiben dieser Migration ein Rollback und ein Rollforward durchführen können. Es kann schwierig werden, wenn Sie etwas falsch machen und mit einer Migration feststecken, die versucht, etwas zu bewirken, das nicht mehr existiert. Am besten löschen Sie die gesamte Datenbank und fangen neu an, wenn Sie nicht zurückgehen können. Seien Sie sich also bewusst, dass Sie möglicherweise etwas sichern müssen.

Prüfen Sie außerdem schema_db auf relevante Spaltennamen in anderen Tabellen, die durch ein has_ oder belongs_to oder ähnliches definiert sind. Wahrscheinlich müssen Sie auch diese bearbeiten.

Und schließlich wäre es verrückt, dies ohne eine Regressionstestreihe zu tun.

1voto

Sie können diesen Befehl ausführen: rails g migration umbenennen_{alte_tabelle_name} zu {neue_tabelle_name}

nachdem Sie die Datei bearbeitet und diesen Code in die Methodenänderung eingefügt haben

rename_table :{alte_tabelle_name}, :{neue_tabelle_name}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X