Tabelle in Schienen umbenennen


154

Ich möchte eine Tabelle umbenennen ... (eine beliebige Tabelle.)

Ich habe diese Codezeile ausprobiert:

ActiveRecord::ConnectionAdapters::SchemaStatements.rename_table(old_name, new_name)

Hier ist das Seltsame. Ich weiß, dass es zum ersten Mal funktioniert hat, aber jetzt wird folgende Fehlermeldung angezeigt: undefinierte Methode `rename_table 'für ActiveRecord :: ConnectionAdapters :: SchemaStatements: Module

Gab es etwas, das ich einstellen musste?

Antworten:


248

Normalerweise tun Sie dies bei einer Migration:

class RenameFoo < ActiveRecord::Migration
  def self.up
    rename_table :foo, :bar
  end

  def self.down
    rename_table :bar, :foo
  end
end

1
Danke das hat funktioniert! Ich bin immer noch verwirrt, warum die vorherige Zeile dies nicht tat. Na ja ..
Tommy

@ Tommy, die rename_tableMethode ist in der definiert ActiveRecord::ConnectionAdapters::SchemaStatements. Es soll in andere Module eingemischt werden. Wenn Sie es direkt ausführen wollten, könnten Sie es tuninclude ActiveRecord::ConnectionAdapters::SchemaStatements; rename_table :foo, :bar
Cam

oder Sie könnten ActiveRecord :: Migration.rename_table (: foo ,: bar) verwenden, wenn Sie dazu geneigt wären. Aber Migration funktioniert am besten. Möchten Sie auch den Namen des Modells ändern oder den Modellnamen als alten beibehalten? In diesem Fall möchten Sie möglicherweise den Tabellennamen im ActiveRecord-Modell mit "set_table_name: bar" angeben.
Aditya Sanghi

1
Sie können das neue Formular auch für Migrationen mit der Methode 'change' anstelle von up & down verwenden. Beispiel
MegaTux

def change, nicht def self.up / def.self.down in modernen Rails-Implementierungen. Letzteres wird lautlos fehlschlagen.
Huertanix

294

Denken Sie daran, dass Sie in Rails> = 3.1 die changeMethode verwenden können.

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

37
Dies wird auch alle Indizes von :old_table_namenach:new_table_name
Gavin Miller

7
Nur ein kleiner Kommentar: Vielleicht ändern Sie zu: old_named_things ,: new_named_things, um die Leute daran zu erinnern, dass Tabellennamen in Activerecord im Allgemeinen pluralisiert sind.
Carpela

24

.rename_tableist eine Instanzmethode, keine Klassenmethode, daher Class.methodfunktioniert das Aufrufen nicht. Stattdessen müssen Sie eine Instanz der Klasse erstellen und die Methode für die Instanz wie folgt aufrufen : Class.new.method.

[BEARBEITEN] In diesem Fall ActiveRecord::ConnectionAdapters::SchemaStatementshandelt es sich nicht einmal um eine Klasse (wie von cam hervorgehoben), was bedeutet, dass Sie nicht einmal eine Instanz davon erstellen können, wie oben angegeben. Und selbst wenn Sie das Beispiel von cam verwenden class Foo; include ActiveRecord::ConnectionAdapters::SchemaStatements; def bar; rename_table; end; end;würden, würde es nicht funktionieren, da dies rename_tableeine Ausnahme auslöst.

Auf der anderen Seite ActiveRecord::ConnectionAdapters::MysqlAdapter handelt es sich um eine Klasse, und es ist wahrscheinlich, dass Sie diese Klasse verwenden müssen, um Ihre Tabelle umzubenennen (oder SQLite oder PostgreSQL, je nachdem, welche Datenbank Sie verwenden). Jetzt ist es zufällig ActiveRecord::ConnectionAdapters::MysqlAdapterbereits über zugänglich Model.connection, sodass Sie in der Lage sein sollten Model.connection.rename_table, jedes Modell in Ihrer Anwendung zu verwenden. [/BEARBEITEN]

Wenn Sie jedoch eine Tabelle dauerhaft umbenennen möchten, würde ich vorschlagen, eine Migration zu verwenden, um dies zu tun. Es ist einfach und die bevorzugte Methode, Ihre Datenbankstruktur mit Rails zu bearbeiten. So geht's:

# Commandline
rails generate migration rename_my_table

# In db/migrate/[timestamp]_rename_my_table.rb:
class RenameMyTable < ActiveRecord::Migration
  def self.up
    rename_table :my_table, :my_new_table
  end

  def self.down
    rename_table :my_new_table, :my_table
  end
end

Anschließend können Sie Ihre Migration mit rake db:migrate(die die self.upMethode rake db:rollbackaufruft self.down) ausführen und mit (welche Aufrufe ) die Migration rückgängig machen.


Ich bin damit einverstanden, dass dies rename_tableeine Instanzmethode ist, die jedoch nicht in einer Klasse definiert ist, sodass Ihr Aufruf zum Aufrufen Class.new.methodnicht funktioniert (Beispiel: Gibt ActiveRecord::ConnectionAdapters::SchemaStatements.newden Fehler oMethodError: undefined method neu 'für ActiveRecord :: ConnectionAdapters :: SchemaStatements: Module`
cam

1
Beachten Sie auch, dass Sie die Datei model.rb umbenennen, ausführen rake db:migrateoder rake db:rollbacknicht umbenennen , wenn der Tabelle ein Modell zugeordnet ist . Sie müssen die Datei model.rb manuell ändern.
9 Monate

1
In neueren Rails-Versionen (z. B. 5.x) können Sie anstelle von self.up und self.down eine Änderungsmethode verwenden , da Rails auch dadurch einen Rollback durchführen kann. Nur dieser Code reicht also aus : . . . . . Durch die Art und Weise: Innerhalb Sie eine verwenden Sie diese Befehle ein : , , , , , , ,def change rename_table :my_table, :my_new_table endchangeadd_columnadd_indexadd_timestampscreate_tableremove_timestampsrename_columnrename_indexrename_table
Schönheit

2
ActiveRecord::Migration.rename_table(:old_table_name, :new_table_name)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.