86

Rails アプリに初期データを入力する rake タスクがあります。たとえば、国、州、携帯電話会社などです。

私が今セットアップした方法は、/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 の設定が機能しません。これは、テーマを追加することにした場合、それを「赤」と呼びましょう。このフィクスチャ ファイルにテーマ ステートメントを追加し、rake タスクを呼び出してデータベースを再シードするだけです。これを行うと、テーマは他のオブジェクトに属し、この再初期化時にそれらの ID が変更されるため、すべてのリンクが壊れます。

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

もしそうなら、どうすればIDをハードコーディングできますか?それには何か欠点がありますか?

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

ベスト プラクティスを取り入れた長く考え抜かれた回答に心から感謝します。

4

7 に答える 7

116

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

Rails 2.3.4 で追加された単純な機能、db/seeds.rb

新しいレーキ タスクを提供します

rake db:seed

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

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

*すでにフィクスチャを作成している場合は、これらを使用して db:seed タスクを追加することもできます。これには、次の内容をシード.rb ファイル (レールキャスト エピソードから) に記述します。

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")
于 2010-01-15T10:38:52.803 に答える
29

通常、2 種類のシード データが必要です。

  • アプリケーションのコアが依存する基本データ。私はこれを共通種と呼んでいます。
  • 環境データ。たとえば、アプリを開発するために、アプリをローカルで作業するために使用できる既知の状態のデータの束があると便利です (上記の Factory Girl の回答はこの種のデータをカバーしています)。

私の経験では、これら 2 種類のデータの必要性に常に直面していました。そこで、Rails のシードを拡張し、db/seeds/ の下に複数の共通シード ファイルを追加し、db/seeds/ENV の下に環境シード データ (db/seeds/development など) を追加できる小さな gem をまとめました。

このアプローチは、シード データに何らかの構造を与えるのに十分であり、次のコマンドを実行するだけで、既知の状態で開発環境またはステージング環境をセットアップする力を与えてくれることがわかりました。

rake db:setup

通常のSQLダンプと同様に、フィクスチャは壊れやすく、維持するのが不安定です。

于 2011-04-04T00:03:46.547 に答える
27

seeds.rbfile またはを使用するFactoryBotのは素晴らしいことですが、これらはそれぞれ固定データ構造とテストに最適です。

gem を使用seedbankすると、シードの制御とモジュール性が向上する可能性があります。レーキ タスクを挿入し、シード間の依存関係を定義することもできます。レーキ タスク リストには次の追加項目があります (例):

rake db:seed                    # Load the seed data from db/seeds.rb, db/seeds/*.seeds.rb and db/seeds/ENVIRONMENT/*.seeds.rb. ENVIRONMENT is the current environment in Rails.env.
rake db:seed:bar                # Load the seed data from db/seeds/bar.seeds.rb
rake db:seed:common             # Load the seed data from db/seeds.rb and db/seeds/*.seeds.rb.
rake db:seed:development        # Load the seed data from db/seeds.rb, db/seeds/*.seeds.rb and db/seeds/development/*.seeds.rb.
rake db:seed:development:users  # Load the seed data from db/seeds/development/users.seeds.rb
rake db:seed:foo                # Load the seed data from db/seeds/foo.seeds.rb
rake db:seed:original           # Load the seed data from db/seeds.rb
于 2013-11-26T07:54:18.640 に答える
27

factory_botは、あなたが達成しようとしていることを実行するように聞こえます。デフォルト定義ですべての共通属性を定義し、作成時にそれらをオーバーライドできます。ファクトリに ID を渡すこともできます。

Factory.define :theme do |t|
  t.background_color '0x000000'
  t.title_text_color '0x000000',
  t.component_theme_color '0x000000'
  t.carrier_select_color '0x000000'
  t.label_text_color '0x000000',
  t.join_upper_gradient '0x000000'
  t.join_lower_gradient '0x000000'
  t.join_text_color '0x000000',
  t.cancel_link_color '0x000000'
  t.border_color '0x000000'
  t.carrier_text_color '0x000000'
  t.public true
end

Factory(:theme, :id => 1, :name => "Lite", :background_color => '0xC7FFD5')
Factory(:theme, :id => 2, :name => "Metallic", :background_color => '0xC7FFD5')
Factory(:theme, :id => 3, :name => "Blues", :background_color => '0x0060EC')

faker と一緒に使用すると、Fixtures をいじる必要なく、非常に迅速にデータベースにアソシエーションを追加できます (yuck)。

レーキタスクにこのようなコードがあります。

100.times do
    Factory(:company, :address => Factory(:address), :employees => [Factory(:employee)])
end
于 2009-04-17T19:33:18.860 に答える
1

ここで説明されているように、Rails にはデータをシードする方法が組み込まれています。

もう 1 つの方法は、次のようなより高度な、または簡単なシード処理のために gem を使用することです

この gem の主な利点と私がそれを使用する理由は、データ読み込みの依存関係や環境ごとのシード データなどの高度な機能があることです。

この回答はGoogleで最初にあったため、最新の回答を追加します。

于 2014-05-05T14:21:40.637 に答える
-3

最良の方法は、器具を使用することです。

注:フィクスチャは直接挿入を行い、モデルを使用しないことに注意してください。データを取り込むコールバックがある場合は、回避策を見つける必要があります。

于 2009-04-17T19:10:58.587 に答える
-5

データベースの移行に追加します。そうすれば、更新時に全員が取得できます。すべてのロジックをruby/railsコードで処理するため、明示的なID設定をいじる必要はありません。

于 2009-04-17T19:13:32.060 に答える