26

Rake db:seedは、アプリのデフォルトのデータベース値をデータベースに入力しますか?したがって、すでにシードがあり、それに追加する必要がある場合はどうなりますか(シードを必要とする新しい機能を追加します)。私の経験では、rake db:seedを再度実行すると、既存のコンテンツがすでに追加されているため、既存のコンテンツが2倍になりました。

必要なのはいくつかのシードを追加することです。実行すると、最新のシードを追加し、既存のシードを無視する必要があります。これをどうやってやるの?(私が通常行う汚い、noobの方法は、データベース全体を切り捨ててからシードを再度実行することですが、本番環境で行うのはあまり賢明ではありませんよね?)

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倍になることもありません。
  2. ユーザー名「admin」とロール「admin」のレコードは存在しません。上記のレコードが作成されます。
  3. ユーザー名/役割の基準の1つだけが満たされる場合、上記のレコードが作成されることに注意してください。適切な基準を使用して、一意性を維持したいものを複製しないようにします。
于 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呼び出しを1回実行するだけで済み、何かが存在せず、作成する必要がある場合にのみ再度呼び出す必要があると思います。

于 2012-12-10T22:45:54.500 に答える
1

この種のものに対する私の好みは、seeds.rbファイルを使用するのではなく、カスタムrakeタスクを作成することです。

ユーザーを一括作成しようとしている場合は、データを使用して.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

追加する


から

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

別の簡単な代替手段:

#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 に答える
-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 に答える
-4

User.delete_allアプリケーションに含めたすべてのモデルに対して、seed.rb ファイルの先頭に と を追加するだけです。確かに重複する値はありません。

于 2011-11-15T13:30:23.170 に答える