Rails自动分配已经存在的id

我创build了一个新的logging,如下所示:

truck = Truck.create(:name=>name, :user_id=>2)

我的数据库目前有几千个卡车实体,但是我把id分配给了其中的几个,这样就留下了一些id。 所以发生了什么事是轨道创build与id = 150的项目,它工作正常。 但是,它试图创build一个项目,并为其分配ID = 151,但该ID可能已经存在,所以我看到这个错误:

ActiveRecord::RecordNotUnique (PG::Error: ERROR: duplicate key value violates unique constraint "companies_pkey" DETAIL: Key (id)=(151) already exists.

而下一次我运行的动作,它会简单地分配ID 152,这将正常工作,如果该值尚未采取。 我怎样才能得到轨道检查一个ID是否已经存在,然后分配它?

谢谢!

编辑

卡车id是什么被复制。 用户已经存在,在这种情况下是一个常数。 这实际上是一个遗留问题,我不得不处理。 一种select是重新创build表让let rails自动分配每个id。 我开始认为这可能是最好的select,因为我还有其他一些问题,但是这样做的迁移将非常复杂,因为卡车在许多其他表格中是外键。 有没有一种简单的方法来使用轨道创build一个新的表,其中已经存储在卡车下的相同的数据,自动分配的ID和维护所有现有的关系?

Rails可能使用内置的PostgreSQL序列。 一个序列的想法是,它只能使用一次。

最简单的解决scheme是使用如下查询将company.id列的序列设置为表中的最高值:

 SELECT setval('company_id_seq', (SELECT max(id) FROM company)); 

我猜你的序列名称为“company_id_seq”,表名“company”,列名“id”…请用正确的replace它们。 您可以通过SELECT pg_get_serial_sequence('tablename', 'columname');获取序列名称SELECT pg_get_serial_sequence('tablename', 'columname'); 或者使用\d tablename查看表定义。

另一种解决scheme是覆盖公司类中的save()方法,以便在保存之前手动设置新行的公司ID。

我做了这个解决了我的问题。

 ActiveRecord::Base.connection.tables.each do |t| ActiveRecord::Base.connection.reset_pk_sequence!(t) end 

我find了reset_pk_sequence! 从这个线程。 http://www.ruby-forum.com/topic/64428

基于@Apie的答案 。

您可以完成一项任务,并在需要时运行:

 rake database:correction_seq_id 

你创build这样的任务:

 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 

听起来像一个数据库问题,而不是一个Rails的问题。 是否有可能你的数据库在你的id列上有不正确的身份种子? 要testing尝试做一对夫妇直接插入到您的数据库,看看是否存在相同的行为。