For PostgreSQL, rename_column is implemented as a simple ALTER TABLE ... RENAME COLUMN ... and stores indexes.
MySQL versions (both of them) execute ALTER TABLE ... CHANGE ... and also store indexes.
It is assumed that the SQLite version will copy the entire table (with indexes), discard the old one, and then copy the copy back to the original table name. Copy seems to handle renaming the column when copying indexes:
def copy_table(from, to, options = {})
and inside copy_table_indexes :
columns = index.columns.map {|c| rename[c] || c }.select do |column| to_column_names.include?(column) end
So, standard drivers will save your indexes when you execute rename_column , and the SQLite driver makes some effort to do this.
The API documentation does not indicate any specific behavior, although other drivers may do other things. The closest documentation comes to say something about indexes, this is in active_record/migration.rb :
rename_column(table_name, column_name, new_column_name) : Renames the column, but retains the type and content.
I think that any driver will keep indexes, but there is no guarantee; a driver writer would certainly be foolish not to keep indexes.
This is not a definitive or authoritative answer, but your indexes must be preserved if you use standard PostgreSQL, MySQL (or one of them), or SQLite drivers.
Note that even if the index itself is preserved, renaming the column does not guarantee that the index name will be changed. This should not be a problem if you are not doing something (e.g. manual deletion) that takes care of the index name and not which columns are involved.
The above behavior has been changed in Rails 4 :
- In Rails 4.0, when you rename a column or table, the corresponding indexes are also renamed. If you have migrations that rename indexes, they are no longer needed.
Thus, ActiveRecord will automatically rename indexes to match the new table or column names when renaming a table or column. Thanks to sequielo for the heads-up.