【问题标题】:Ruby on Rails Seed DataRuby on Rails 种子数据
【发布时间】:2015-05-08 14:08:16
【问题描述】:

我是 Ruby/Rails 新手。我目前正在学习使用 Rake 和 seed.rb 文件的 Rails 控制台和数据库。

我应该:

  • 将具有唯一标题和正文的帖子添加到seeds.rb。
  • 在创建唯一帖子之前,请验证它是否存在于数据库中。仅有的 如果没有,请播种帖子。
  • 运行 rake db:seed 几次,启动 Rails 控制台并确认 您的独特帖子仅被播种一次。
  • 重复创建一个独特的评论并确认它也是唯一的 播种一次。

老实说,我不知道如何着手处理这个问题。我应该使用 rails 控制台或直接从 seed.rb 文件添加帖子?任何指导将不胜感激。

【问题讨论】:

  • “运行 rake db:seed 几次”你只会运行一次。
  • “在创建唯一帖子之前,请验证它是否存在于数据库中。如果不存在,则只为帖子播种。”这是没有意义的。创建数据库时,您将为其播种。事实上 rake db:setup 运行 rake db:seed。种子提供了使用依赖于应用程序的数据或“样本数据”预填充数据库的概念
  • 给你这些指示的人不应该给任何人指示。
  • @jBeas 本教程要求 OP 多次运行 rake db:seed 的原因是为了测试播种是幂等的。您是正确的,您通常不会多次播种。
  • 您应该使用种子文件创建帖子,并使用控制台验证它只创建过一次。

标签: ruby-on-rails ruby rails-console


【解决方案1】:

Seeding 是用数据填充数据库的过程。

有两种方法可以做到这一点。

你可以使用ActiveRecord Migrations

class AddInitialProducts < ActiveRecord::Migration
  def up
    5.times do |i|
      Product.create(name: "Product ##{i}", description: "A product.")
    end
  end

  def down
    Product.delete_all
  end
end

或者您可以将其存储在单独的seeds.rb 文件中

5.times do |i|
  Product.create(name: "Product ##{i}", description: "A product.")
end

然后,运行rake db:seed

来源

http://edgeguides.rubyonrails.org/active_record_migrations.html#migrations-and-seed-data

【讨论】:

  • 正如 Darkmouse 向您展示的那样,seeds.rb 是一个普通的 ruby​​ 文件,您可以在其中放置您想要的任何代码。因此,您还可以放置测试帖子是否存在的代码。但如果你真的想使用唯一性验证,我建议创建一个 Post 模型和一个 Comment 模型。
【解决方案2】:

尽管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 时,titlebody 这两个属性都是唯一的,因此如果您尝试对以下属性执行相同操作:

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 一起玩的练习 - 这是您解决问题的方法之一。

希望有帮助!

【讨论】:

    猜你喜欢
    • 2016-11-21
    • 1970-01-01
    • 2016-12-16
    • 1970-01-01
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    • 2016-10-14
    • 1970-01-01
    相关资源
    最近更新 更多