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 80

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

звучит для меня как проблема с базой данных, а не проблема с рельсами. Возможно ли, что ваша база данных имеет неправильное идентификационное семя на вашем ? Чтобы проверить, попробуйте сделать пару вставок непосредственно в вашу базу данных и посмотреть, существует ли такое же поведение.