¿Cómo manejo nombres de índice demasiado largos en una migración ActiveRecord de Ruby on Rails?


Estoy tratando de agregar un índice único que se crea a partir de las claves foráneas de cuatro tablas asociadas:

add_index :studies,
  ["user_id", "university_id", "subject_name_id", "subject_type_id"],
  :unique => true

La limitación de la base de datos para el nombre del índice hace que la migración falle. Aquí está el mensaje de error:

Index name 'index_studies_on_user_id_and_university_id_and_subject_name_id_and_subject_type_id' on table 'studies' is too long; the limit is 64 characters

¿Cómo puedo manejar esto? Puedo especificar un nombre de índice?

Author: Andrew Marshall, 2011-03-26

5 answers

Proporcione la opción :name para add_index, por ejemplo:

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

Si se usa la opción :index en references en un bloque create_table toma el mismo hash de opciones que add_index como su valor.

 456
Author: fl00r,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-23 18:59:15

También puede cambiar el nombre del índice en las definiciones de columna dentro de un bloque create_table (como se obtiene del generador de migración).

create_table :studies do |t|
  t.references :user, index: {:name => "index_my_shorter_name"}
end
 138
Author: Craig Walker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-25 17:14:22

En PostgreSQL, el límite predeterminado es de 63 caracteres. Debido a que los nombres de índice deben ser únicos, es bueno tener un poco de convención. Utilizo (he ajustado el ejemplo para explicar construcciones más complejas):

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

El índice normal habría sido:

:index_studies_on_professor_id_and_user_id

La lógica sería:

  • index se convierte en idx
  • Nombre singular de la tabla
  • Sin palabras de unión
  • No _id
  • Orden alfabético

Que normalmente hace el trabajo.

 27
Author: ecoologic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-27 17:44:34

También puedes hacer

t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')

Como en la API Ruby on Rails.

 15
Author: tomascharad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-27 17:36:09

Similar a la respuesta anterior: Simplemente use la tecla 'name' con su línea normal add_index:

def change
  add_index :studies, :user_id, name: 'my_index'
end
 5
Author: Nadeem Yasin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-27 17:32:11