Jaki jest najlepszy sposób na zapełnienie bazy danych w Railsach?


82

Mam zadanie rake, które wypełnia pewne początkowe dane w mojej aplikacji rails. Na przykład kraje, stany, operatorzy komórkowi itp.

Sposób, w jaki to teraz skonfigurowałem, jest taki, że mam kilka instrukcji create w plikach w / db / fixtures i zadanie rake, które je przetwarza. Na przykład jeden model, który mam, to motywy. Mam plik theme.rb w / db / fixtures, który wygląda następująco:

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"

Chodzi o to, że chcę zainstalować kilka motywów stockowych dla użytkowników na początek. Mam problem z tą metodą.

Ustawienie ID nie działa. Oznacza to, że jeśli zdecyduję się dodać motyw, nazwijmy go „czerwonym”, chciałbym po prostu dodać instrukcję motywu do tego pliku ustawień i wywołać zadanie rake, aby ponownie umieścić bazę danych. Jeśli to zrobię, ponieważ motywy należą do innych obiektów i ich id zmienia się po ponownej inicjalizacji, wszystkie linki są zepsute.

Moje pytanie brzmi przede wszystkim: czy to dobry sposób na obsadzenie bazy danych? W poprzednim poście polecono mi to.

Jeśli tak, jak mogę na stałe zakodować identyfikatory i czy są jakieś wady?

Jeśli nie, jaki jest najlepszy sposób zapełnienia bazy danych?

Naprawdę docenię długie i przemyślane odpowiedzi, które zawierają najlepsze praktyki.

Odpowiedzi:


113

Aktualizacja, ponieważ te odpowiedzi są nieco nieaktualne (chociaż niektóre nadal mają zastosowanie).

Prosta funkcja dodana w rails 2.3.4, db / seeds.rb

Zapewnia nowe zadanie prowizji

rake db:seed

Dobry do wypełniania typowych rekordów statycznych, takich jak stany, kraje itp.

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

* Zauważ, że możesz użyć urządzeń, jeśli już je utworzyłeś, aby zapełnić je zadaniem db: seed, umieszczając w swoim pliku seeds.rb (z odcinka railscast):

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

W Railsach 3.x użyj „ActiveRecord :: Fixtures” zamiast stałej „Fixtures”

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

28

Zwykle wymagane są 2 typy danych początkowych.

  • Podstawowe dane, na których może opierać się rdzeń Twojej aplikacji. Nazywam to zwykłymi nasionami.
  • Dane środowiskowe , na przykład w celu opracowania aplikacji przydatne jest posiadanie zbioru danych w znanym stanie, których możemy użyć do lokalnej pracy nad aplikacją (powyższa odpowiedź Factory Girl obejmuje tego rodzaju dane).

Z mojego doświadczenia wynika, że ​​zawsze potrzebowałem tych dwóch typów danych. Więc stworzyłem mały klejnot, który rozszerza seedy Railsów i pozwala na dodawanie wielu wspólnych plików seedów do db / seeds / i wszelkich danych środowiskowych w db / seeds / ENV, na przykład db / seeds / development.

Zauważyłem, że to podejście jest wystarczające, aby nadać moim danym seed pewną strukturę i daje mi możliwość skonfigurowania mojego środowiska programistycznego lub tymczasowego w znanym stanie, po prostu wykonując:

rake db:setup

Urządzenia są delikatne i kruche w utrzymaniu, podobnie jak zwykłe zrzuty sql.


Lubię terminy „dane systemowe” i „dane środowiska uruchomieniowego”, które opisują rzeczy, na których opiera się kod, a dane od użytkowników. Czasami granica między nimi jest niewyraźna.
— Tim Abell

27

Wygląda na to, że factory_bot zrobi to, co chcesz osiągnąć. Można zdefiniować wszystkie wspólne atrybuty w domyślnej definicji, a następnie nadpisać je w czasie tworzenia. Możesz również przekazać identyfikator do fabryki:

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')

Użyty z fakerem może bardzo szybko zapełnić bazę danych skojarzeniami bez konieczności majstrowania przy Fixtures (fuj).

Mam taki kod w zadaniu prowizji.

100.times do
    Factory(:company, :address => Factory(:address), :employees => [Factory(:employee)])
end

11
FactoryGirl jest tak naprawdę przeznaczone do testowania zamiast urządzeń, ale może być również używane do ładowania rzeczy do produkcji. Użyj zadania rake, które ma db: migrate jako warunek wstępny, aby załadować wszystkie domyślne dane. Może zajść potrzeba uczynienia zadania rake na tyle inteligentnym, aby nie tworzyło kopii istniejących danych.
— Bob Aman

2
Używanie FactoryGirl do nasion nie jest zalecane, sprawdź ten post .
— blackbiron

26

Używanie seeds.rbpliku lub FactoryBotjest świetne, ale te są odpowiednio świetne do stałych struktur danych i testowania.

seedbankKlejnot może dać większą kontrolę i modułowość do swoich nasion. Wstawia zadania rake, a także możesz zdefiniować zależności między nasionami. Twoja lista zadań rake będzie zawierała następujące dodatki (np.):

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

1

Railsy mają wbudowany sposób wysyłania danych, jak wyjaśniono tutaj .

Innym sposobem byłoby użycie klejnotu do bardziej zaawansowanego lub łatwiejszego rozstawienia, takiego jak: bank nasion .

Główną zaletą tego klejnotu i powodem, dla którego go używam, jest to, że ma zaawansowane możliwości, takie jak zależności ładowania danych i dane początkowe dla poszczególnych środowisk.

Dodanie aktualnej odpowiedzi, ponieważ pojawiła się ona jako pierwsza w Google.


-3

Najlepszym sposobem jest użycie urządzeń.

Uwaga: pamiętaj, że urządzenia wstawiają bezpośrednio i nie używają modelu, więc jeśli masz wywołania zwrotne, które wypełniają dane, musisz znaleźć obejście.


-4

Dodaj go do migracji baz danych, dzięki czemu wszyscy otrzymają go podczas aktualizacji. Obsługuj całą swoją logikę w kodzie ruby ​​/ rails, więc nigdy nie musisz mieszać z jawnymi ustawieniami identyfikatora.


Jeśli muszę zmienić początkowe dane, podczas migracji może się pojawić bałagan. Twój drugi komentarz nie ma sensu. linki za pomocą kluczy obcych zostaną zniszczone
— Tony

c = Category.create (stuff) p = Post.create (stuff) p.category = c Nie ma potrzeby jawnego ustawiania identyfikatorów. Jeśli zmienisz dane początkowe, po prostu utworzysz nową migrację. Całkiem proste.
— Matt Rogish,

czyli przy założeniu, że skojarzenia mogą być wykonane w momencie tworzenia obiektu. oto przykład, w którym uważam, że twoja logika zawodzi ... popraw mnie, jeśli się mylę. zapełniam DB motywami szablonów. user id = 1 tworzy szablon o id = 2 iz motywem o id = 4. w tym momencie w bazie danych znajduje się rekord w następujący sposób: template: id = 2, user_id = 1, theme_id = 4. teraz, jeśli ponownie zainicjuję bazę danych, identyfikator motywu = 4 to teraz identyfikator motywu = 10 ... a następnie szablon użytkownika ma nieprawidłowy motyw
— Tony

cóż, zależy to od tego, co rozumiesz przez „ponowne zainicjowanie” - jeśli zaczniesz od zera, Railsy obsługują wszystkie asocjacje automagicznie. Jeśli mocno zakodujesz wartości identyfikatorów (źle !!!), to tak, to wybuchnie.
— Matt Rogish,

ok, zaczynam rozumieć twój punkt widzenia, ale muszę uruchomić ten scenariusz przez ciebie. zapełniam bazę danych tabelą wyszukiwania krajów. USA => id kraju = 1. następnie użytkownik tworzy restaurację istniejącą w USA. wiersz bazy danych restauracji ma country_id = 1. to jest bardzo częste, prawda? później zdecyduję, że chcę dodać więcej krajów ... jeśli wyczyszczę bazę danych i ponownie zapełnię tabelę wyszukiwania krajów, teraz nazwa kraju restauracji nie jest już dokładna, chyba że identyfikator jest taki sam. jak sobie z tym poradzić?
— Tony
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.