1. ホーム
  2. ruby-on-rails

[解決済み] Railsでデータベースをシードする最良の方法は何ですか?

2023-06-03 15:50:50

質問

rakeのタスクで、railsアプリの初期データを投入するものがあります。 例えば、国、州、携帯電話会社などです。

私が今設定している方法は、/db/fixtures にあるファイルにたくさんの create 文があり、それらを処理する rake タスクがあるというものです。 たとえば、私が持っている 1 つのモデルはテーマです。 私は /db/fixtures に以下のような theme.rb ファイルを持っています。

Theme.delete_all
Theme.create(:id => 1, :name=>'Lite', :background_color=>'0xC7FFD5', :title_text_color=>'0x222222',
                      :component_theme_color=>'0x001277', :carrier_select_color=>'0x7683FF', :label_text_color=>'0x000000',
                      :join_upper_gradient=>'0x6FAEFF', :join_lower_gradient=>'0x000000', :join_text_color=>'0xFFFFFF',
                      :cancel_link_color=>'0x001277', :border_color=>'0x888888', :carrier_text_color=>'0x000000', :public => true)

Theme.create(:id => 2, :name=>'Metallic', :background_color=>'0x000000', :title_text_color=>'0x7299FF',
                      :component_theme_color=>'0xDBF2FF', :carrier_select_color=>'0x000000', :label_text_color=>'0xDBF2FF',
                      :join_upper_gradient=>'0x2B25FF', :join_lower_gradient=>'0xBEFFAC', :join_text_color=>'0x000000',
                      :cancel_link_color=>'0xFF7C12', :border_color=>'0x000000', :carrier_text_color=>'0x000000', :public => true)

Theme.create(:id => 3, :name=>'Blues', :background_color=>'0x0060EC', :title_text_color=>'0x000374',
                      :component_theme_color=>'0x000374', :carrier_select_color=>'0x4357FF', :label_text_color=>'0x000000',
                      :join_upper_gradient=>'0x4357FF', :join_lower_gradient=>'0xffffff', :join_text_color=>'0x000000',
                      :cancel_link_color=>'0xffffff', :border_color=>'0x666666', :carrier_text_color=>'0x000000', :public => true)
puts "Success: Theme data loaded"

ここでのアイデアは、ユーザーが始めるためにいくつかのストックテーマをインストールしたいということです。 この方法には問題があります。

ID を設定してもうまくいきません。 つまり、テーマを追加することに決めたら、それを 'Red' と呼ぶことにして、この fixture ファイルにテーマステートメントを追加して、データベースを再シードするために rake タスクを呼び出したいだけなのです。 そうすると、テーマは他のオブジェクトに属しており、この再初期化によってそれらの ID が変更されるため、すべてのリンクが壊れてしまうのです。

私の質問は、まず第一に、これはデータベースのシードを処理する良い方法なのでしょうか? 以前の投稿で、これは私に勧められました。

もしそうなら、どのようにIDをハードコードすればよいのでしょうか、また、それによるデメリットはあるのでしょうか?

そうでない場合、データベースをシードする最良の方法は何でしょうか。

私は、ベストプラクティスを取り入れた、長くて考え抜かれた答えを本当に評価します。

どのように解決するのですか?

これらの回答は若干古くなっているため、更新しています(一部はまだ適用されますが)。

rails 2.3.4で追加されたシンプルな機能、db/seeds.rb。

新しいrakeタスクを提供します。

rake db:seed

州、国などのような一般的な静的レコードに入力するのに適しています...

http://railscasts.com/episodes/179-seed-data

*フィクスチャをすでに作成している場合は、seeds.rbファイルに次のように記述することで、db:seedタスクに投入することもできることに注意してください(railscastのエピソードより)。

require 'active_record/fixtures'
Fixtures.create_fixtures("#{Rails.root}/test/fixtures", "operating_systems")

Rails 3.xでは、'Fixtures' 定数の代わりに 'ActiveRecord::Fixtures' を使用します。

require 'active_record/fixtures'
ActiveRecord::Fixtures.create_fixtures("#{Rails.root}/test/fixtures", "fixtures_file_name")