0

rake タスクを使用して、データベースに初期データを入力しています。最初のいくつかの ID を使用して、テーブルに一連のエントリを作成したいので、それらは常に存在し、常にそれらの ID を持ちます。開発環境で、誰かがレコードを追加/削除/変更してもかまいませんが、常に最初の 5 つの ID に値が必要です。以下は、私の lib/tasks/bootstrap.rb ファイルの簡略版です。

namespace :bootstrap do
    desc "Create the default problem types"
    task :default_problem_types => :environment do
        ProblemType.create( :id => 1, :name => 'Wrong location', :description => 'blah' )
        ProblemType.create( :id => 2, :name =>  'Wrong name', :description => 'blah' )
        ProblemType.create( :id => 3, :name =>  'Wrong details', :description => 'blah' )
        ProblemType.create( :id => 4, :name =>  'Duplicate', :description => 'blah' )
        ProblemType.create( :id => 5, :name =>  'No longer exists', :description => 'blah' )
    end

    desc "Run all bootstrapping tasks"
    task :all => [:default_problem_types]
end

これは、空のデータベースで正常に機能します。problem_types テーブルに 5 つの新しいエントリを作成します。

1 - Wrong Location 
2 - Wrong name 
3 - Wrong details 
4 - Duplicate 
5 - No longer exists

問題は、もう一度実行すると、ID が 6、7、8、9、10 の 5 つの新しいレコードが作成されることです。これは、既に存在する create() 呼び出しに ID を指定したにもかかわらずです。次のSQLを実行しようとすると、これらの呼び出しが失敗することが予想されます。

insert into problem_types (id, name, description) values (1, 'foo', 'bar');

...失敗します:

エラー 1062 (23000): キー 'PRIMARY' のエントリ '1' が重複しています

ID が既に存在する場合に create() メソッドを失敗させるにはどうすればよいですか?

ありがとう。

4

2 に答える 2

0

動的find_or_create_byまたはfind_or_initialize_byメソッドを使用します。これらの詳細については、Active Record クエリ インターフェイスの Rails ガイドを参照してください。ProblemType名前で重複を作成せずに、それぞれに次のようなものを書くことができます。

problem_type = ProblemType.find_or_initialize_by_name('Wrong location')
problem_type.description = "blah"
problem_type.save

@benchwarmerに同意します。主キーを自分で管理しないことをお勧めします。セマンティック値の数値識別子が必要な場合は、別の列を追加して、それに応じてその値を設定してみてください。

于 2013-02-18T20:03:08.447 に答える
0

経験則: 自分で ID を割り当てないでください。データベースに仕事をさせてください。問題名を一意にしたい場合は、validates_uniqueness_of :nameモデル ファイルに追加できます。同じ名前が存在する場合、レコードは作成されません。

于 2013-02-18T19:07:49.050 に答える