Skip to content

Indexes lose uniqueness constraint when change_column is executed #1344

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
justindell opened this issue Jun 13, 2025 · 0 comments
Open

Indexes lose uniqueness constraint when change_column is executed #1344

justindell opened this issue Jun 13, 2025 · 0 comments

Comments

@justindell
Copy link
Contributor

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant