附加到rake db:seed并在rails中运行而不复制数据

cor*_*ded 25 ruby ruby-on-rails seeding ruby-on-rails-3

Rake db:seed使用应用程序的默认数据库值填充数据库吗?那么如果你已经有一个种子并且你需要添加它(你添加了一个需要种子的新功能).根据我的经验,当我再次运行rake db:seed时,它已经添加了现有内容,因此现有内容变为双倍.

我需要的是添加一些种子,当它运行时,它应该只添加最新的种子,并忽略现有的种子.我该如何解决这个问题?(我通常这样做的脏,noob方式是截断我的整个db然后再次运行种子,但是在生产中这不是很聪明,对吧?)

ssc*_*rus 38

更简洁的方法是使用find_or_create_by,如下所示:

User.find_or_create_by_username_and_role(
  :username => "admin",
  :role => "admin",
  :email => "me@gmail.com")
Run Code Online (Sandbox Code Playgroud)

以下是可能的结果:

  1. 存在用户名"admin"和角色"admin"的记录.如果新电子邮件已存在,则不会使用新电子邮件更新此记录,但也不会加倍.
  2. 用户名"admin"和角色"admin"不存在记录.将创建上述记录.
  3. 请注意,如果只满足其中一个用户名/角色条件,则会创建上述记录.使用正确的标准可确保您不会复制您想要保持唯一的内容.

  • 1.错了.那里的任何属性都不会更新.如果要更新记录,则需要进行后续更新.如名称所示,它将查找或创建,而不是查找或更新. (2认同)
  • @BillLeeper - 你说得对.感谢您纠正我的假设 - 我刚刚更新了答案. (2认同)

Jes*_*ott 14

我这样做......当我需要添加用户时

在seeds.rb中:

if User.count == 0
  puts "Creating admin user"
  User.create(:role=>:admin, :username=>'blagh', :etc=>:etc)
end
Run Code Online (Sandbox Code Playgroud)

你可以获得更多有趣的东西,但在这种情况下,你可以根据需要重新运行它.

  • 您可能还必须在创建之前查找特定记录.检查它们的存在:例如`User.create(:name =>"Bob"),除非User.find_by_name("Bob")` (4认同)

Lex*_*xun 8

另一个可能会带来轻微性能优势的选项:

# This example assumes that a role consists of just an id and a title.

roles = ['Admin', 'User', 'Other']
existing_roles = Role.all.map { |r| r.title }

roles.each do |role|
  unless existing_roles.include?(role)
    Role.create!(title: role)
  end
end
Run Code Online (Sandbox Code Playgroud)

我认为这样做,你只需要做一个db调用来获取存在的数组,然后你只需要再次调用,如果没有东西需要创建.

  • existing_roles = Role.all.map {| r | r.title}可以写成Role.all.collect(&:title),或者在Rails 3.2中只是Role.pluck(:title) (4认同)