Rename_column заботится об индексах?
Скажем, у нас есть что-то вроде этого:
add_column :users, :single, :boolean
add_index :users, :single
а потом мы делаем
rename_column :users, :single, :married
Будет ли ActiveRecord и / или база данных обрабатывать переименование индекса, или мне придется вручную удалить индекс и добавить его снова?
1 ответ
Для 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.
Обратите внимание, что даже если сам индекс сохраняется после переименования столбца, нет гарантии, что имя индекса будет изменено. Это не должно быть проблемой, если вы не делаете что-то (например, добавление вручную), которое заботится об имени индекса, а не о том, какие столбцы задействованы.
Вышеупомянутое поведение изменилось в Rails 4:
- В Rails 4.0, когда столбец или таблица переименовываются, связанные индексы также переименовываются. Если у вас есть миграции, которые переименовывают индексы, они больше не нужны.
Таким образом, ActiveRecord будет автоматически переименовывать индексы в соответствии с именами новой таблицы или столбца при переименовании таблицы или столбца. Спасибо sequielo за хедз-ап на это.