已经存在的 Rails 自动分配 id

我创建了一个新的记录,如下所示:

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

我的数据库里目前有几千个云梯车的实体,但我把 ID 分配给了其中几个,这样就留下了一些 ID。因此,现在的情况是,Rail 创建 id = 150的 item,并且它工作得很好。但是它会尝试创建一个条目并赋值它 id = 151,但是这个 id 可能已经存在了,所以我看到了这个错误:

ActiveRecord: : RecordNotUnique (PG: : ERROR: ERROR: 重复键值违反唯一约束“ Companies _ pkey” 密钥(id) = (151)已经存在

下一次我运行这个操作时,它将简单地分配 id 152,如果没有使用这个值,那么它将很好地工作。如何在分配 ID 之前获得 ails 来检查 ID 是否已经存在?

谢谢!

剪辑

正在复制的是卡车的 ID。用户已经存在,在本例中是常量。实际上这是我必须处理的遗产问题。其中一个选择是重新创建表,以便 Rails 这次自动分配每个 id。我开始认为这可能是最好的选择,因为我还有其他一些问题,但是这样做的迁移将是非常复杂的,因为 Truck 在许多其他表中都是一个外键。有没有一种简单的方法,让 ails 创建一个新表,其中的数据与 Truck 下已经存储的数据相同,并且具有自动分配的 ID 和维护所有现有的关系?

28458 次浏览

Sounds to me like a database problem and not a Rails problem. Is it possible your database has an improper identity seed on your id column? To test try doing a couple inserts directly into your database and see if the same behavior exists.

Rails is probably using the built-in PostgreSQL sequence. The idea of a sequence is that it is only used once.

The simplest solution is to set the sequence for your company.id column to the highest value in the table with a query like this:

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

I am guessing at your sequence name "company_id_seq", table name "company", and column name "id" ... please replace them with the correct ones. You can get the sequence name with SELECT pg_get_serial_sequence('tablename', 'columname'); or look at the table definition with \d tablename.

An alternate solution is to override the save() method in your company class to manually set the company id for new rows before saving.

I did this which solved the issue for me.

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

I found the reset_pk_sequence! from this thread. http://www.ruby-forum.com/topic/64428

Based on @Apie answer.

You can make a task and run when you need with:

rake database:correction_seq_id

You create tasks like this:

rails g task database correction_seq_id

And in the file generated (lib/tasks/database.rake) put:

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

I resolved this issue by following command.

Run this in your rails console

ActiveRecord::Base.connection.reset_pk_sequence!('table_name')