附加到rake db:seed并在rails中运行而不复制数据
Rake db:seed用应用程序的默认数据库值填充你的数据库吧? 那么,如果您已经有一个种子并且需要添加它(您添加了一个需要种子的新function)。 根据我的经验,当我再次运行rake db:seed时,它已经添加了现有内容,因此现有内容变为了两倍。
我需要的是添加一些种子,当它运行时,它应该只添加最新的种子,并忽略现有的种子。 我该如何解决这个问题? (我通常这样做的脏,noob方式是截断我的整个数据库然后再次运行种子,但是在生产中这不是很聪明,对吧?)
我这样做……当我需要添加用户时
在seeds.rb中:
if User.count == 0 puts "Creating admin user" User.create(:role=>:admin, :username=>'blagh', :etc=>:etc) end
你可以获得更多有趣的东西,但在这种情况下,你可以根据需要重新运行它。
更find_or_create_by
方法是使用find_or_create_by
,如下所示:
User.find_or_create_by_username_and_role( :username => "admin", :role => "admin", :email => "me@gmail.com")
以下是可能的结果:
- 存在用户名“admin”和角色“admin”的记录。 如果新电子邮件已存在,则不会使用新电子邮件更新此记录,但也不会加倍。
- 用户名“admin”和角色“admin”不存在记录。 将创建上述记录。
- 请注意,如果只满足其中一个用户名/角色条件,则会创建上述记录。 使用正确的标准可确保您不会复制要保持唯一的内容。
另一种可能带来轻微性能优势的选择:
# 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调用来获取存在的数组,然后你只需要再次调用,如果不存在并且需要创建。
我喜欢这种事情是创建一个自定义rake任务而不是使用seeds.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
添加
从
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_ofvalidation或比较所有必要属性的唯一性validation但不使用跳过validation的方法 。
一个真正可以理解的方法是评论现有数据,这就是我做的方式,它对我来说很好
=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")
完成后,只需删除评论
另一个琐碎的选择:
#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
只需添加User.delete_all
以及seed.rb文件开头的应用程序中包含的所有模型。 肯定不会有任何重复的值。