比如,我们有这样的东西:

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

然后我们就开始了

rename_column :users, :single, :married

ActiveRecord和/或数据库是否也会处理索引的重命名,还是必须手动删除索引并再次添加?

推荐答案

对于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文档没有指定任何特定的行为,不过其他驱动程序可能会执行其他操作.文档中关于索引的最接近的说法是:

rename_column(table_name, column_name, new_column_name):重命名列,但保留类型和内容.

我认为任何驱动程序都会保留索引,但这并不能保证;如果驱动程序编写人员不保存索引,那肯定是愚蠢的.

这不是一个明确或权威的答案,但如果使用标准的PostgreSQL、MySQL(任意一种)或SQLite驱动程序,则应该保留索引.


请注意,即使索引本身在列重命名后仍然存在,也不能保证索引name会被更改.这应该不会是一个问题,除非你做的事情(比如手动删除它)关心的是索引名,而不是涉及哪些列.

上述行为changed in Rails 4:

  • 在Rails 4.0中,当列或表被重命名时,相关的索引也会被重命名.如果有重命名索引的迁移,则不再需要它们.

因此,当您重命名表或列时,ActiveRecord将自动重命名索引以匹配新的表或列名.多亏了sequielo人的提醒.

Ruby-on-rails相关问答推荐

将会话_store 与:active_record一起使用

Rails 7涡轮框架和多种形式与形式值有关

Rails 7 Active Record::SessionStore -如何获取控制器中当前会话的数据库ID?

Rails Routing:在具有自己的路由的名称空间下组织路由

这种使用on:的语法在 Ruby on Rails 中意味着什么?

如何在 Ruby on Rails 中正确存储 BigDecimal

Rails 控制台 - 更新 Gem 后的弃用通知

Ruby 地理定位Ruby /插件

如何在 Windows 中更新 ruby

使用 Ruby on Rails 从原始 IP 地址获取用户国家名称

将 Amazon SES 与 Rails ActionMailer 结合使用

.increment vs += 1

如何使用 Ruby 在现有 PDF 上编辑或书写?

我收到在扫描下一个令牌时发现无法启动任何令牌的字符

Rails:进行不可逆转的迁移是不是很糟糕?

从 ActiveRecord 对象中提取两个属性的快捷方式?

:javascript haml 标签中的内联Ruby ?

Rails,Docker:主机不存在:默认

如何设置 MiniTest?

Rails:每个环境的初始化程序?