Как мне обрабатывать слишком длинные имена индексов при переносе Ruby on Rails ActiveRecord?
Я пытаюсь добавить уникальный индекс, который создается из внешних ключей четырех связанных таблиц:
add_index :studies,
["user_id", "university_id", "subject_name_id", "subject_type_id"],
:unique => true
Ограничение базы данных для имени индекса приводит к сбою миграции. Вот сообщение об ошибке:
Имя индекса 'index_studies_on_user_id_and_university_id_and_subject_name_id_and_subject_type_id' в таблице 'Studies' слишком длинное; ограничение составляет 64 символа
Как я могу справиться с этим? Могу ли я указать другое имя индекса?
Ответы
Ответ 1
Укажите параметр :name
для add_index
, например:
add_index :studies,
["user_id", "university_id", "subject_name_id", "subject_type_id"],
:unique => true,
:name => 'my_index'
При использовании опции :index
в references
в блоке create_table
в качестве значения берется тот же хеш опций, что и в add_index
:
t.references :long_name, index: { name: :my_index }
Ответ 2
Вы также можете изменить имя индекса в определениях столбцов в блоке create_table
(например, из генератора миграции).
create_table :studies do |t|
t.references :user, index: {:name => "index_my_shorter_name"}
end
Ответ 3
В PostgreSQL предел по умолчанию - 63 символа. Поскольку имена индексов должны быть уникальными, приятно иметь небольшое соглашение. Я использую (я объяснил пример, чтобы объяснить более сложные конструкции):
def change
add_index :studies, [:professor_id, :user_id], name: :idx_study_professor_user
end
Нормальный индекс был бы:
:index_studies_on_professor_id_and_user_id
Логика будет:
-
index
становится idx
- Имя отдельной таблицы
- Не присоединяется к словам
- Нет
_id
- Алфавитный порядок
Что обычно выполняет задание.
Ответ 4
Вы также можете сделать
t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
как в API Ruby on Rails.
Ответ 5
Как и в предыдущем ответе: просто используйте ключ "name" с вашей обычной линией add_index:
def change
add_index :studies, :user_id, name: 'my_index'
end
Ответ 6
У меня была эта проблема, но с функцией timestamps
. Он автоматически генерировал индекс для updated_at, который превысил ограничение в 63 символа:
def change
create_table :toooooooooo_loooooooooooooooooooooooooooooong do |t|
t.timestamps
end
end
Имя индекса 'index_toooooooooo_loooooooooooooooooooooooooooooong_on_updated_at' в таблице 'toooooooooo_loooooooooooooooooooooooooooooooong' слишком длинное; ограничение составляет 63 символа
Я пытался использовать timestamps
для указания имени индекса:
def change
create_table :toooooooooo_loooooooooooooooooooooooooooooong do |t|
t.timestamps index: { name: 'too_loooooooooooooooooooooooooooooong_updated_at' }
end
end
Тем не менее, он пытается применить имя индекса к полям updated_at
и created_at
:
Имя индекса 'too_long_updated_at' в таблице 'toooooooooo_loooooooooooooooooooooooooooooong' уже существует
Наконец, я отказался от timestamps
и просто создал метки времени:
def change
create_table :toooooooooo_loooooooooooooooooooooooooooooong do |t|
t.datetime :updated_at, index: { name: 'too_long_on_updated_at' }
t.datetime :created_at, index: { name: 'too_long_on_created_at' }
end
end
Это работает, но я бы хотел услышать, если это возможно с помощью метода timestamps
!