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.

Tony
źródło

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")
ajhit406
źródło
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.

james2m
źródło
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
Hates_
źródło
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
Yuri
źródło
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.

SimonW
źródło
-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.

p01nd3xt3r
źródło
-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.

Matt Rogish
źródło
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