Перейменування таблиці в рейки


154

Я хочу перейменувати таблицю ... (будь-яку таблицю.)

Я спробував цей рядок коду:

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

Ось дивна річ. Я знаю, що я працював уперше, але тепер я отримую цю помилку: невизначений метод `rename_table 'для ActiveRecord :: ConnectionAdapters :: SchemaStatements: Module

Чи потрібно було щось встановити?

Відповіді:


248

Ви зазвичай робите такі речі під час міграції:

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

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

1
Дякую, що спрацювало! Я все ще спантеличений, чому попередній рядок не був. О добре ..
Томмі

@Tommy, rename_tableметод визначений у ActiveRecord::ConnectionAdapters::SchemaStatements. Він призначений для змішування з іншими модулями. Якщо ви хотіли запустити його безпосередньо, я думаю, ви могли б зробити цеinclude ActiveRecord::ConnectionAdapters::SchemaStatements; rename_table :foo, :bar
камер

або ви можете скористатися ActiveRecord :: Migration.rename_table (: foo,: bar), якщо ви були так схильні. Але міграція працює найкраще. Ви також хочете змінити назву моделі або зберегти назву моделі як стару? Якщо так, можливо, ви захочете вказати ім'я таблиці в моделі ActiveRecord, використовуючи "set_table_name: bar".
Aditya Sanghi

1
Ви також можете використовувати нову форму для міграцій методом "зміни", а не вгору та вниз. приклад
MegaTux

у сучасних реалізаціях Rails не змінювати, а не визначати self.up / def.self.down. Виконання останнього не вдасться мовчки.
huertanix

294

Пам'ятайте, що в Rails> = 3.1 ви можете використовувати changeметод.

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

37
Це також перемістить будь-які індекси з :old_table_nameдо:new_table_name
Гевін Міллер

7
Лише невеликий коментар: Можливо, змініть на: old_named_things,: new_named_things, щоб нагадати людям, що імена таблиць у активному записі зазвичай множинні.
Карпела

24

.rename_tableце метод примірника, а не метод класу, тому виклик Class.methodне працює. Натомість вам доведеться створити екземпляр класу та викликати метод на екземпляр, наприклад:Class.new.method .

[EDIT] У цьому випадку ActiveRecord::ConnectionAdapters::SchemaStatementsце навіть не клас (як вказував cam), а це означає, що ви навіть не можете створити його екземпляр відповідно до сказаного вище. І навіть якщо ви використовували приклад камери class Foo; include ActiveRecord::ConnectionAdapters::SchemaStatements; def bar; rename_table; end; end;, він все одно не буде працюватиrename_table викликає виняток.

З іншого боку, ActiveRecord::ConnectionAdapters::MysqlAdapter це клас, і, ймовірно, цей клас вам доведеться використовувати для перейменування таблиці (або SQLite або PostgreSQL, залежно від бази даних, яку ви використовуєте). Тепер, як це відбувається, ActiveRecord::ConnectionAdapters::MysqlAdapterвже доступний через Model.connection, тому ви повинні бути повністю здатні це зробитиModel.connection.rename_table , використовуючи будь-яку модель у вашій програмі. [/ EDIT]

Однак, якщо ви хочете остаточно перейменувати таблицю, я б запропонував використовувати для цього міграцію. Це простий і бажаний спосіб маніпулювання структурою вашої бази даних з Rails. Ось як це зробити:

# 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

Потім ви можете запустити міграцію за допомогою rake db:migrate(який викликає self.upметод) та використовувати rake db:rollback(який викликає self.down) скасування міграції.


Я погоджуюся, що rename_tableце метод екземпляра, але він не визначений у класі, тому ваша пропозиція викликати Class.new.methodне буде працювати (наприклад: ActiveRecord::ConnectionAdapters::SchemaStatements.newдає oMethodError: undefined method нову помилку 'для ActiveRecord :: ConnectionAdapters :: SchemaStatements: Module`
cam

1
Також варто зазначити, що якщо у вас є модель, пов’язана з таблицею, ви перейменовуєте, запускаєте rake db:migrateабо rake db:rollbackне будете перейменовувати файл model.rb. Вам потрібно буде вручну змінити файл model.rb.
9monkeys

1
У новіших версіях Rails (наприклад, 5.x) ви можете використовувати метод зміни замість self.up та self.down , оскільки Rails також може виконувати відкат шляхом цього. Так що цей код достатньо: def change rename_table :my_table, :my_new_table end. . . . . До речі: Всередині з changeвас у використанні цих команд: add_column, add_index, add_timestamps, create_table, remove_timestamps, rename_column, rename_index,rename_table
краса

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.