Rails автоматическое назначение идентификатора, который уже существует
создать новую запись Вот так:
truck = Truck.create(:name=>name, :user_id=>2)
в моей базе данных в настоящее время есть несколько тысяч объектов для truck, но я назначил идентификаторы нескольким из них, таким образом, что некоторые идентификаторы остались доступными. Итак, что происходит, rails создает элемент с id = 150, и он отлично работает. Но затем он пытается создать элемент и назначить ему id = 151, но этот идентификатор уже может существовать, поэтому я вижу эту ошибку:
ActiveRecord::RecordNotUnique (PG::Error: ERROR: duplicate key value violates unique constraint "companies_pkey"
DETAIL: Key (id)=(151) already exists.
и в следующий раз, когда я запустить действие, он просто назначит id 152, который будет работать нормально, если это значение еще не принято. Как я могу получить rails, чтобы проверить, существует ли идентификатор до его назначения?
спасибо!
редактировать
идентификатор грузовика-это то, что дублируется. Пользователь уже существует и является константой в этом случае. На самом деле это проблема наследия, с которой мне приходится иметь дело. Один вариант, это создать таблицу на рельсы автоматически присваивать каждому идентификатору в этот раз. Я начинаю думать, что это может быть лучшим выбором, потому что у меня есть несколько других проблем, но миграция для этого будет очень сложной, потому что грузовик является внешним ключом во многих других таблицах. Будет ли простой способ создать rails новую таблицу с теми же данными, которые уже хранятся под Truck, с автоматически назначенными идентификаторами и поддержанием всех существующих отношений?
4 ответа:
Rails, вероятно, использует встроенную последовательность PostgreSQL. Идея последовательности заключается в том, что она используется только один раз.
самое простое решение-установить последовательность для вашего company.id столбец с самым высоким значением в таблице с запросом типа этого:
SELECT setval('company_id_seq', (SELECT max(id) FROM company));
Я предполагаю, что на ваше имя последовательности "company_id_seq", имя таблицы "фирмы", и имя столбца "идентификатор" ... пожалуйста, замените их на правильные. Вы можете получить имя последовательности с помощью
SELECT pg_get_serial_sequence('tablename', 'columname');
или посмотреть на определение таблицы с\d tablename
.альтернативным решением является переопределение метода save () в классе компании, чтобы вручную установить идентификатор компании для новых строк перед сохранением.
Я сделал это, что решило проблему для меня.
ActiveRecord::Base.connection.tables.each do |t| ActiveRecord::Base.connection.reset_pk_sequence!(t) end
Я нашел reset_pk_sequence! из этой темы. http://www.ruby-forum.com/topic/64428
на основе @Apie ответ.
вы можете сделать задачу и запустить, когда вам нужно с:
rake database:correction_seq_id
вы создаете такие задачи:
rails g task database correction_seq_id
и в созданном файле (
lib/tasks/database.rake
) положить:namespace :database do desc "Correction of sequences id" task correction_seq_id: :environment do ActiveRecord::Base.connection.tables.each do |t| ActiveRecord::Base.connection.reset_pk_sequence!(t) end end end