说,我们有这样的事情:
add_column :users, :single, :boolean
add_index :users, :single
然后我们做
rename_column :users, :single, :married
ActiveRecord和/或数据库是否也会处理索引的重命名,还是我必须手动删除索引并再次添加它?
答案 0 :(得分:94)
对于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 将被更改。这不应该是一个问题,除非你正在做一些关心索引名称而不是涉及哪些列的东西(比如手动删除它)。
以上行为changed in Rails 4:
- 在Rails 4.0中,当重命名列或表时,也会重命名相关索引。如果您具有重命名索引的迁移,则不再需要它们。
因此,重命名表或列时,ActiveRecord将自动重命名索引以匹配新的表或列名。感谢sequielo对此进行了单挑。