Как вы пишете миграцию для переименования модели ActiveRecord и ее таблицы в Rails?

351

Мне страшно назвать и понять, что в моем приложении Rails есть лучший набор имен для моих моделей.
Можно ли использовать миграцию для переименования модели и ее соответствующей таблицы?

  • 10
    Я предложил добавить «ActiveRecord» к этому вопросу, чтобы улучшить поиск в поисковых системах. Я искал это с помощью "таблицы переименования ActiveRecord".
  • 5
    Если вы используете миграции, эта проблема сложнее, чем кажется. Выбранное решение говорит просто вернуться и вручную переименовать модель, контроллер и т. Д. После изменения имени таблицы. Если вы сделаете это, все старые миграции, которые ссылаются на вашу модель по старому имени, завершатся неудачно. Поэтому, когда кто-то клонирует ваш репозиторий и пытается запустить rake db:migrate , произойдет сбой. Вы могли бы вернуться и изменить эти имена в процессе миграции, но это может стать грязным. Возможно, вам лучше создать совершенно новую модель, чем переименовывать ее.
Показать ещё 2 комментария
Теги:
migration
activerecord

4 ответа

482
Лучший ответ

Вот пример:

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

Мне пришлось перейти и переименовать файл объявления модели вручную.

Edit:

В Rails 3.1 и 4 ActiveRecord::Migration::CommandRecorder знает, как отменить переименование переименования, так что вы можете сделать это:

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

(Вам все равно придется просматривать и вручную переименовывать свои файлы.)

  • 0
    Да, но это не меняет название модели, не так ли?
  • 0
    это меняет только имя таблицы.
Показать ещё 9 комментариев
54

В Rails 4 все, что мне нужно было сделать, это изменение def

def change
  rename_table :old_table_name, :new_table_name
end

И все мои индексы позаботились обо мне. Мне не нужно было вручную обновлять индексы, удаляя старые и добавляя новые.

И он работает, используя изменение для перехода вверх или вниз по отношению к индексам.

39

Другие ответы и комментарии охватывают переименование таблицы, переименование файлов и grepping через ваш код.

Я хотел бы добавить еще несколько оговорок:

Позвольте использовать реальный пример, с которым я столкнулся сегодня: переименование модели из "Торговец" в "Бизнес".

  • Не забудьте изменить имена зависимых таблиц и моделей в та же миграция. Одновременно я изменил модели Merchant и MerchantStat на Business and BusinessStat. В противном случае мне пришлось бы делать слишком много выбора и выбирать при выполнении поиска и замены.
  • Для любых других моделей, которые зависят от вашей модели с помощью внешних ключей, имена столбцов внешнего ключа других таблиц будут получены из вашего исходного названия модели. Поэтому вы также захотите сделать некоторые вызовы rename_column на этих зависимых моделях. Например, мне пришлось переименовать столбец "merchant_id" в "business_id" в разных таблицах соединений (для отношения has_and_belongs_to_many) и других зависимых таблиц (для нормальных отношений has_one и has_many). В противном случае я бы столкнулся с такими столбцами, как "business_stat.merchant_id", указывающий на "business.id". Вот хороший ответ о переименовании столбцов.
  • Когда grepping, не забудьте найти единственное, множественное, заглавное, строчные и даже UPPERCASE (которые могут встречаться в комментариях) версии ваших строк.
  • Лучше сначала искать множественные версии, затем единственные. Что если у вас есть нерегулярное множественное число - например, у моих торговцев:: бизнес-пример - вы можете исправить все неправильные множественные числа. В противном случае вы можете получить, например, "бизнес" (3 с) в качестве промежуточное состояние, что приводит к еще большему количеству поиска и замены.
  • Не слепо заменять все случаи. Если ваши имена моделей сталкиваются с обычными условиями программирования, со значениями в других моделях или с текстового контента в ваших взглядах, вы можете оказаться слишком чрезмерным. В моем примере я хотел изменить свое имя модели на "Бизнес", но по-прежнему относятся к ним как к "торговцам" в содержании в моем пользовательском интерфейсе. У меня также была "коммерческая роль" для моих пользователей в CanCan - это была путаница между ролью продавца и моделью Merchant, которая заставила меня переименовать модель в первую очередь.
20

Вам также нужно заменить индексы:

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

И переименуйте свои файлы и т.д., как описано ниже.

Смотрите: http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

Удостоверьтесь, что вы можете откат и перемотка вперед после записи этой миграции. Это может стать сложным, если вы получите что-то не так и застряли в миграции, которая пытается создать то, что больше не существует. Лучше всего удалите всю базу данных и начните снова, если вы не сможете откат. Поэтому имейте в виду, что вам, возможно, понадобится что-то сделать.

Также: проверьте schema_db для любых соответствующих имен столбцов в других таблицах, определенных has_ ​​или belongs_to или что-то в этом роде. Возможно, вам также придется отредактировать их.

И, наконец, делать это без набора регрессионных тестов будет гайкой.

  • 10
    Что касается миграций rails 4.0.0.beta1, нет необходимости обновлять индексы вручную. AR обновляет его самостоятельно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню