尽管seed-ing 的意图是运行一次以填充数据库,但没有技术限制阻止您多次运行rake db:seed 命令。即使没有清理/重新创建数据库。
在这种情况下,请尝试 db/seeds.rb
的以下代码
post_atrributes = [
{ title: "Sample Title 1", body: "Sample body 1" },
{ title: "Sample Title 2", body: "Sample body 2" },
{ title: "Sample Title 3", body: "Sample body 3" },
]
post_attributes.each do |attributes|
Post.create(attributes) unless Post.where(attributes).first
end
首先,我们为每个要创建的Post 定义一个属性数组。
稍后,我们将遍历该数组(使用post_attributes.each do |attributes|),并尝试创建一个新的Post,除非找到具有指定属性的Post。
在 Rails 中,有一个非常奇特的方法 first_or_create,它正是这样做的 - 查询数据库以获取指定的属性 (where(attributes)),如果没有找到 - 根据提供的属性创建新记录。
post_atrributes = [
{ title: "Sample Title 1", body: "Sample body 1" },
{ title: "Sample Title 2", body: "Sample body 2" },
{ title: "Sample Title 3", body: "Sample body 3" },
]
post_attributes.each do |attributes|
Post.where(attributes).first_or_create
end
此时,您可以使用rake db:seed“播种”数据库,并通过以下方式检查数据库中存储的内容(运行rails console):
Post.all.map(&:title)
假设您在运行rake db:seed 之前有空数据库,它应该只包含3 个Posts。用post_attributes中的属性指定的那些。
现在,如果您尝试再次修改您的 db/seeds.rb,为另一个 Post 添加一个属性:
post_atrributes = [
{ title: "Sample Title 1", body: "Sample body 1" },
{ title: "Sample Title 2", body: "Sample body 2" },
{ title: "Sample Title 3", body: "Sample body 3" },
{ title: "Another Post", body: "WOW!" },
]
post_attributes.each do |attributes|
Post.where(attributes).first_or_create
end
运行rake db:seed,并在控制台中检查:
Post.all.map(&:title)
您可以看到,只创建了一个新的Post。标题为“另一个帖子”的那个。
在您的问题中,我了解到,在创建新的 Post 时,title 和 body 这两个属性都是唯一的,因此如果您尝试对以下属性执行相同操作:
post_atrributes = [
{ title: "Sample Title 1", body: "Sample body 1" },
{ title: "Sample Title 1", body: "Sample body 2" },
]
这将创建两个独立的Posts,因为它们定义了不同的body 属性。
对于Comments,你可以做类似的事情。
再次,正如 jBeas 之前提到的 - seed-ing 有不同的目的,但如果这只是与 ActiveRecord 一起玩的练习 - 这是您解决问题的方法之一。
希望有帮助!