Open
Description
When running change_column in a migration, indexes are dropped first and then recreated. However, the recreated index doesn't have the same flags as the original one. Here is a bash script that sets up a new rails app, creates a unique column, and changes the length of the column. Notice that the index is no longer unique:
#!/bin/bash
SQL_SERVER_USERNAME="your_sql_server_username"
SQL_SERVER_PASSWORD="your_sql_server_password"
set -x
rails new change_column_bug
cd change_column_bug || exit 1
cat >"config/database.yml" <<EOF
development:
adapter: sqlserver
encoding: utf8
username: $SQL_SERVER_USERNAME
password: $SQL_SERVER_PASSWORD
database: change_column_bug
host: localhost
EOF
echo "gem 'activerecord-sqlserver-adapter'" >>Gemfile
bundle install
rails generate model Item name:string:uniq
rails db:reset
rails db:migrate
echo -e "\033[0;31m$(cat db/schema.rb | grep index)\033[0m"
rails generate migration LimitItemNameLengthTo100
SECOND_MIGRATION=$(ls db/migrate/*_limit_item_name_length_to100.rb)
cat >"$SECOND_MIGRATION" <<EOF
class LimitItemNameLengthTo100 < ActiveRecord::Migration[7.1]
def change
change_column :items, :name, :string, limit: 100
end
end
EOF
rails db:migrate
echo -e "\033[0;31m$(cat db/schema.rb | grep index)\033[0m"
Here is the interesting part of the output if you don't wish to run the script:
++ cat db/schema.rb
++ grep index
+ echo -e '\033[0;31m t.index ["name"], name: "index_items_on_name", unique: true\033[0m'
t.index ["name"], name: "index_items_on_name", unique: true
+ rails generate migration LimitItemNameLengthTo100
invoke active_record
create db/migrate/20250613151945_limit_item_name_length_to100.rb
++ ls db/migrate/20250613151945_limit_item_name_length_to100.rb
+ SECOND_MIGRATION=db/migrate/20250613151945_limit_item_name_length_to100.rb
+ cat
+ rails db:migrate
== 20250613151945 LimitItemNameLengthTo100: migrating =========================
-- change_column(:items, :name, :string, {limit: 100})
-> 0.2264s
== 20250613151945 LimitItemNameLengthTo100: migrated (0.2264s) ================
++ cat db/schema.rb
++ grep index
+ echo -e '\033[0;31m t.index ["name"], name: "index_items_on_name"\033[0m'
t.index ["name"], name: "index_items_on_name"
Thanks!