How do I handle too long index names in a Ruby on Rails ActiveRecord migration?

Solution 1:

Provide the :name option to add_index, e.g.:

add_index :studies,
  ["user_id", "university_id", "subject_name_id", "subject_type_id"], 
  unique: true,
  name: 'my_index'

If using the :index option on references in a create_table block, it takes the same options hash as add_index as its value:

t.references :long_name, index: { name: :my_index }

Solution 2:

You can also change the index name in column definitions within a create_table block (such as you get from the migration generator).

create_table :studies do |t|
  t.references :user, index: {:name => "index_my_shorter_name"}
end

Solution 3:

In PostgreSQL, the default limit is 63 characters. Because index names must be unique it's nice to have a little convention. I use (I tweaked the example to explain more complex constructions):

def change
  add_index :studies, [:professor_id, :user_id], name: :idx_study_professor_user
end

The normal index would have been:

:index_studies_on_professor_id_and_user_id

The logic would be:

  • index becomes idx
  • Singular table name
  • No joining words
  • No _id
  • Alphabetical order

Which usually does the job.