【问题标题】:Seeded database key values conflicting with factory bot create/build种子数据库键值与工厂机器人创建/构建冲突
【发布时间】:2018-05-03 17:06:34
【问题描述】:

我们的 rails 数据库预先植入了一些静态模型的数据。例如,我们有一个通过db/seeds.rb 填充/更新的DocumentType 模型。用户无法修改此模型。

不过,这似乎与 factory_bot 不兼容;当我尝试:

create(:document_type)

我收到一条错误消息:

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

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

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

document_type 工厂

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 来插入/更新......所以固定装置似乎不是一个好的播种选项.

如果有人有任何想法,我很好奇。谢谢!

【问题讨论】:

  • 您的测试数据库中真的需要种子数据吗?通常,这是您希望避免在测试开始时在数据库中包含任何数据的事情,除了测试中指定的数据。您检查过 DatabaseCleaner gem 吗?
  • 你是如何定义你的document_type 工厂的?
  • @sovalina - 我在问题中添加了工厂,谢谢
  • @PaulByrne - 我还没有检查过那个宝石。会做的,谢谢!我想如果我在这个项目上回到 5 年以上,我们可能会以不同的方式处理种子数据;事实上,我们在源 API 中硬编码了模型 id,以引用预期存在的某些模型……这意味着我们需要具有“正确”id 的种子。回想起来,这似乎很糟糕。可能应该使用非递增的唯一字段(如 slug)。但事实上,我们的生产服务正在播种预期存在的数据,并且方法会引用这些特定的 ID。

标签: ruby-on-rails rspec ruby-on-rails-5 factory-bot rspec-rails


【解决方案1】:

也许尝试对您的 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

【讨论】:

  • 要使+ 30 动态化,请考虑以下内容:id { Model.maximum(:id) + 1 }
猜你喜欢
  • 2021-12-16
  • 2021-12-29
  • 2018-08-18
  • 2023-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多