rails db seed文件在播种前删除某些表中的现有数据的最佳方法,以防止重复数据

时间:2014-07-19 21:50:05

标签: ruby-on-rails activerecord seeding

我在rails应用程序中有几个表。 一个表包含我现在想要更新的种子数据,而不涉及其他表。 但是,如果我没有弄错的话,只使用rake db:seed会复制我的数据。

我可以包含像这样的命令吗?  ModelName.delete_all 在种子文件的开头?

这样做的最佳方式是什么?

3 个答案:

答案 0 :(得分:2)

根据我的最佳做法,我将使用first_or_initialize方法确保我们创建更新现有数据而不会破坏它们。例如,您已在种子数据中创建了多个用户,例如

3.times do |i|
   User.create(email: "abc@example.com", name: "Test #{i}")
end

然后你应该这样做

3.times do |i|
   user = User.where(email: "abc@example.com").first_or_initialize
   user.name = "New Test #{i}"
   user.save
end

答案 1 :(得分:1)

你可以,但是如果ModelName有任何关联,你就会搞砸你的外键ID。听起来很危险。

现在说...我在种子文件中有一些代码可以将一小组非常具体的数据加载到模型中。我有一个包含我想要的所有字段的哈希,然后我遍历它并查找和更新或创建行。

providers = {
  foo: {name: 'Foo', ...},
  bar: {name: 'Bar', ...}
}

providers.each do |(code, attrs)|
  p = Provider.find_by(code: code) || Provider.new(code: code)
  p.update!(attrs)
end

答案 2 :(得分:1)

  

我可以在种子文件的开头包含ModelName.delete_all之类的命令吗?

当然,你可以,seed.rb只是一系列ruby(和rails)命令,所以你可以随心所欲地做任何事情。

在我的一些项目中,我使用以下snipet从seed.rb中删除整个数据库:

tables = ActiveRecord::Base.connection.tables - ['schema_migrations']

tables.each do |table|
  ActiveRecord::Base.connection.execute "DELETE FROM `#{table}`"
  ActiveRecord::Base.connection.execute "ALTER TABLE `#{table}` AUTO_INCREMENT = 1"
end

使用此snipet,无需担心关联或链接ID。唯一剩下的垃圾是公共文件夹中的链接文件(例如通过运输工具或paper_trail)。在这种情况下,您需要手动清理这些文件夹。

snipet的另一个优点是,您不必在项目中添加新表时更新它,因为它会删除所有表,除了导轨使用的schema_migrations以外跟踪已包含/正在等待的迁移