Rename_column заботится об индексах? - PullRequest
57 голосов
/ 18 июля 2011

Скажем, у нас есть что-то вроде этого:

add_column :users, :single, :boolean
add_index :users, :single

, а потом мы делаем

rename_column :users, :single, :married

Будет ли ActiveRecord и / или база данных обрабатывать переименование индекса, или мне придется вручную удалить индекс и добавить его снова?

1 Ответ

96 голосов
/ 18 июля 2011

Для PostgreSQL rename_column реализован как простой ALTER TABLE ... RENAME COLUMN ... и сохраняет индексы.

Версии MySQL (обе) делают ALTER TABLE ... CHANGE ..., и это также сохраняет индексы.

Похоже, что версия SQLite копирует всю таблицу (с индексами), удаляет старую, а затем копирует копию обратно в исходное имя таблицы. Копирование, кажется, обрабатывает переименование столбца при копировании индексов:

def copy_table(from, to, options = {})
  #...
  copy_table_indexes(from, to, options[:rename] || {})

и внутри copy_table_indexes:

columns = index.columns.map {|c| rename[c] || c }.select do |column|
  to_column_names.include?(column)
end

Итак, стандартные драйверы сохранят ваши индексы, когда вы выполните rename_column, а драйвер SQLite приложит некоторые усилия для этого.

В документации API не указывается какое-либо конкретное поведение, поэтому другие драйверы могут выполнять другие действия. Самая близкая документация касается всего, что говорится об индексах, это в active_record/migration.rb:

rename_column(table_name, column_name, new_column_name): переименовывает столбец, но сохраняет тип и содержимое.

Я думаю, что любой драйвер сохранит индексы, но нет никакой гарантии; писатель драйвера, конечно, будет глупо не сохранять индексы.

Это не окончательный или авторитетный ответ, но ваши индексы должны быть сохранены, если вы используете стандартные драйверы PostgreSQL, MySQL (любой из них) или SQLite.


Обратите внимание, что даже если сам индекс сохраняется после переименования столбца, нет гарантии, что индекс name будет изменен. Это не должно быть проблемой, если вы не делаете что-то (например, отбрасываете это вручную), которое заботится об имени индекса, а не о том, какие столбцы задействованы.

Вышеупомянутое поведение изменено в Rails 4 :

  • В Rails 4.0, когда столбец или таблица переименовываются, связанные индексы также переименовываются. Если у вас есть миграции, которые переименовывают индексы, они больше не нужны.

Таким образом, ActiveRecord автоматически переименовывает индексы в соответствии с именами новой таблицы или столбца при переименовании таблицы или столбца. Спасибо sequielo за помощь в этом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...