种子数据库键值与工厂机器人创建/构建相冲突

问题描述 投票:0回答:2

我们的 Rails 数据库预先植入了一些静态模型的一些数据。例如,我们有一个通过

DocumentType
填充/更新的
db/seeds.rb
模型。用户无法修改此模型。

然而,这似乎与factory_bot 配合得不太好;当我尝试:

create(:document_type)

我收到一条错误消息:

ActiveRecord::RecordNotUnique: PG::UniqueViolation:错误:重复的键值违反了唯一约束“document_types_pkey” 详细信息:密钥 (id)=(1) 已存在。

每次运行测试时,都会发生此错误,但尝试保存的密钥(id)会增加。然后,最终,当测试超出种子数据的范围时,测试就会通过。

我不明白的是为什么factory_bot实际上设置了

id
值并且在保存记录时不让数据库分配它。

文档类型工厂

FactoryBot.define do
  factory :document_type do
    label 'Alien Spacecraft License'
    description 'It should be obvious, I think'
    created_at { Time.now - 30.days }
    updated_at { Time.now - 30.days }
  end
end

尝试修复

我尝试的是创建一个完全模仿 seeds.rb 文件中内容的固定文件 - 当我这样做时,factory_bot 会遵循固定装置中设置的

id
值。但这会导致很多重复的工作(我必须使种子与赛程保持同步)。

我已经考虑过使用固定装置来填充数据库,但不幸的是,在我们的例子中,我们在种子数据中使用硬编码 ID 来插入/更新......所以固定装置似乎不是一个好的播种选项。

我很好奇是否有人有任何想法。谢谢!

ruby-on-rails rspec ruby-on-rails-5 factory-bot rspec-rails
2个回答
4
投票

也许尝试对您的

document_type
工厂ID进行排序,以在种子的最后一个ID之后开始增量

FactoryBot.define do
  factory :document_type do
    sequence(:id) {|n| n + 30 } #i.e n + last id known in seed
  end
end

0
投票

就我而言,这个假设是错误的:

我不明白的是为什么factory_bot实际上是在设置id值而不是在保存记录时让数据库分配它。

FactoryBot 未设置 ID。这是数据库自动增量的错误。通过手动设置 ID,自动增量值不会随之增加。因此,即使您已经用完该值,它仍然设置为

1

为此修复,在加载我的灯具后,我手动重新计算了序列号:

ActiveRecord::Base.connection.execute("SELECT setval('#{klass.table_name}_id_seq', (SELECT MAX(id) FROM #{klass.table_name}))")
© www.soinside.com 2019 - 2024. All rights reserved.