Создаю новую запись вот так:
truck = Truck.create(:name=>name, :user_id=>2)
В моей базе данных сейчас есть несколько тысяч объектов для грузовиков, но я назначил идентификаторы нескольким из них, так что некоторые идентификаторы остались доступными. Итак, что происходит, rails создает элемент с id = 150, и он отлично работает. Но затем он пытается создать элемент и присвоить ему id = 151, но этот идентификатор может уже существовать, поэтому я вижу эту ошибку:
ActiveRecord::RecordNotUnique (PG::Error: ERROR: duplicate key value violates unique constraint "companies_pkey"
DETAIL: Key (id)=(151) already exists.
И в следующий раз, когда я запущу действие, ему просто будет назначен идентификатор 152, который будет работать нормально, если это значение еще не принято. Как я могу заставить рельсы проверять, существует ли уже идентификатор, прежде чем он его назначит?
Благодарность!
РЕДАКТИРОВАТЬ
Идентификатор грузовика - это то, что дублируется. Пользователь уже существует и в данном случае является постоянным. На самом деле это проблема наследия, с которой мне приходится иметь дело. Один из вариантов - воссоздать таблицу, чтобы на этот раз рельсы автоматически назначали каждый идентификатор. Я начинаю думать, что это может быть лучший выбор, потому что у меня есть несколько других проблем, но миграция для этого была бы очень сложной, потому что Truck является внешним ключом во многих других таблицах. Будет ли простой способ заставить рельсы создать новую таблицу с теми же данными, которые уже хранятся в Truck, с автоматически назначенными идентификаторами и сохранением всех существующих отношений?
Ответы:
Rails, вероятно, использует встроенную последовательность PostgreSQL. Идея последовательности заключается в том, что она используется только один раз.
Самое простое решение - установить для столбца company.id наибольшее значение в таблице с помощью следующего запроса:
SELECT setval('company_id_seq', (SELECT max(id) FROM company));
Я предполагаю, что ваше имя последовательности "company_id_seq", имя таблицы "company" и имя столбца "id" ... замените их на правильные. Вы можете получить имя последовательности
SELECT pg_get_serial_sequence('tablename', 'columname');
или посмотреть определение таблицы с помощью\d tablename
.Альтернативное решение - переопределить метод save () в классе вашей компании, чтобы вручную установить идентификатор компании для новых строк перед сохранением.
источник
create table t (id serial not null primary key); insert into t values (1); insert into t values (default); ERROR: duplicate key value violates unique constraint "t_pkey" DETAIL: Key (id)=(1) already exists.
Я сделал это, и проблема была решена.
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
источник
ActiveRecord::Base.connection.tables.each { |t| ActiveRecord::Base.connection.reset_pk_sequence!(t) }
На основе ответа @Apie .
Вы можете создать задачу и запустить ее, когда вам нужно:
rake database:correction_seq_id
Вы создаете такие задачи:
И в файле created (
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
источник
Для меня это проблема с базой данных, а не проблема с Rails. Возможно ли, что ваша база данных имеет неправильное начальное значение идентификатора в
id
столбце? Чтобы проверить, попробуйте сделать пару вставок прямо в вашу базу данных и посмотрите, существует ли такое же поведение.источник
Я решил эту проблему, выполнив следующую команду.
Запустите это в консоли рельсов
ActiveRecord::Base.connection.reset_pk_sequence!('table_name')
источник