26

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

我需要的是添加一些种子,运行时,它应该只添加最新的种子,而忽略现有的种子。我该怎么做?(我通常做的肮脏的菜鸟方式是截断我的整个数据库然后再次运行种子,但这在生产中不是很聪明,对吧?)

4

8 回答 8

38

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

User.find_or_create_by_username_and_role(
  :username => "admin",
  :role => "admin",
  :email => "me@gmail.com")

以下是可能的结果:

  1. 存在用户名“admin”和角色“admin”的记录。如果该记录已经存在,则不会使用新电子邮件更新该记录,但也不会加倍。
  2. 用户名“admin”和角色“admin”的记录不存在。将创建上述记录。
  3. 请注意,如果仅满足用户名/角色标准之一,它将创建上述记录。使用正确的标准来确保您不会重复您想要保持独特性的内容。
于 2010-12-31T12:52:09.987 回答
14

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

在种子.rb 中:

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

您可以获得比这更有趣的东西,但在这种情况下,您可以根据需要再次运行它。

于 2010-08-13T13:33:53.297 回答
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

我认为这样做,您只需执行一次 db 调用即可获取存在的数组,然后如果某些内容不存在且需要创建,则只需再次调用即可。

于 2012-12-10T22:45:54.500 回答
1

添加


departments = ["this", "that"]
departments.each{|d| Department.where(:name => d).first_or_create}

departments = ["this", "that", "there", "then"]
departments.each{|d| Department.where(:name => d).first_or_create}

这是一个简单的例子,


更新/重命名


departments = ["this", "that", "there", "then"]
departments.each{|d| Department.where(:name => d).first_or_create}

departments = ["these", "those", "there", "then"]
new_names = [['these', 'this'],['those','that']]

new_names.each do |new| 
  Department.where(:name => new).group_by(&:name).each do |name, depts|
    depts.first.update_column :name, new[0] if new[1] == name # skips validation
    # depts[1..-1].each(&:destroy) if depts.size > 1 # paranoid mode
  end
end

departments.each{|d| Department.where(:name => d).first_or_create}

重要提示:您需要更新departments数组的元素,否则肯定会发生重复。

解决方法:添加 validates_uniqueness_of 验证或比较所有必要属性的唯一性验证,但不要使用跳过验证的方法

于 2012-09-05T07:54:47.517 回答
1

我对这类事情的偏好是创建自定义 rake 任务,而不是使用 seed.rb 文件。

如果您尝试批量创建用户,我会使用数据创建一个 .csv 文件,然后创建一个名为 import_users 的 rake 任务并将文件名传递给它。然后循环通过它来创建用户记录。

在 lib/tasks/import_users.rake 中:

namespace :my_app do
  desc "Import Users from a .csv"
  task :import_users => :environment do
    # loop through records and create users
  end
end

然后像这样运行:rake bundle exec my_app:import_users path/to/.csv

如果您需要在生产中运行它:RAILS_ENV=production bundle exec rake my_app:import_users /path/to/.csv

于 2012-09-06T03:24:36.197 回答
-1

一个真正可破解的方法是注释掉现有数据,这就是我所做的,它对我来说很好用

=begin

#Commented Out these lines since they where already seeded 
   PayType.create!(:name => "Net Banking")
   PayType.create!(:name => "Coupouns Pay")

=end
#New data to be used by seeds

PayType.create!(:name => "Check")
PayType.create!(:name => "Credit card")
PayType.create!(:name => "Purchase order")
PayType.create!(:name => "Cash on delivery")

完成后只需删除评论

于 2015-05-14T14:30:28.700 回答
-1

另一个简单的选择:

#categories => name, color 
categories = [
    [ "Category 1", "#e51c23" ],
    [ "Category 2", "#673ab7" ]
]

categories.each do |name, color|
  if ( Category.where(:name => name).present? == false )
    Category.create( name: name, color: color )
  end
end
于 2015-11-18T10:38:14.123 回答
-4

只需User.delete_all在您的 seed.rb 文件的开头添加您在应用程序中包含的所有模型。肯定不会有任何重复的值。

于 2011-11-15T13:30:23.170 回答