2009-04-17 8 views
68

Ho un rake task che popola alcuni dati iniziali nella mia app per rails. Ad esempio, paesi, stati, operatori di telefonia mobile, ecc.Qual è il modo migliore per seminare un database in Rails?

Il modo in cui l'ho impostato ora è che ho un sacco di istruzioni create nei file in/db/fixtures e un'attività rake che li elabora. Ad esempio, un modello che ho è temi. Ho un file theme.rb in/db/infissi che assomiglia a questo:

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" 

L'idea qui è che voglio installare alcuni temi stock per gli utenti di iniziare con. Ho un problema con questo metodo.

L'impostazione dell'ID non funziona. Ciò significa che se decido di aggiungere un tema, chiamiamolo 'Red', quindi vorrei semplicemente aggiungere l'istruzione theme a questo file fixture e chiamare l'attività rake per resettare il database. Se lo faccio, perché i temi appartengono ad altri oggetti e il loro cambiamento di id su questa reinizializzazione, tutti i link sono interrotti.

La mia domanda è prima di tutto, è un buon modo per gestire il seeding di un database? In un post precedente, mi è stato consigliato.

Se è così, come posso codificare gli ID e ci sono degli svantaggi?

In caso contrario, qual è il modo migliore per eseguire il seeding del database?

Apprezzerò molto le risposte lunghe e ponderate che incorporano le migliori pratiche.

+0

Potresti accettare la risposta più aggiornata? –

+0

Proprio fatto. Grazie per il promemoria – Tony

risposta

99

Aggiornamento poiché queste risposte sono leggermente sorpassate (anche se alcune sono ancora valide).

Semplice funzionalità aggiunta nei binari 2.3.4, db/semi.rb

Fornisce una nuova task rake

rake db:seed 

Per popolamento record statici comuni, come gli stati, paesi, ecc ...

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

* Si noti che è possibile utilizzare dispositivi se si li avevo già creati per popolare anche con l'attività db: seed inserendo quanto segue nel file seeds.rb (dall'episodio railscast):

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

Per Rails uso 3.x 'ActiveRecord :: Infissi' invece di 'Fixtures' costante

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

Invece di utilizzare creazioni esplicite, utilizzare i file YAML. Con una semplice sintassi, è possibile inserire tutti i valori di un oggetto. In realtà, se si sa qualcosa sul test delle rotaie, questo è il modo standard per seminare il database di test. Dai un'occhiata a queste pagine:
http://railspikes.com/2008/2/1/loading-seed-data http://quotedprintable.com/2007/11/16/seed-data-in-rails

+5

che conosco sui test delle rotaie. Non sto testando la mia app, sto seminando il mio database per lo sviluppo e la produzione. inoltre, l'articolo che mi hai inviato si conclude sostenendo il mio metodo di seeding del database. – Tony

-4

Il modo migliore è quello di utilizzare apparecchi.

Nota: tenere presente che i dispositivi fanno inserimenti diretti e non usano il modello, quindi se si dispone di callback che popolano i dati sarà necessario trovare una soluzione alternativa.

0

Aggiungilo alle migrazioni del database, in questo modo tutti lo ricevono mentre si aggiornano. Gestisci tutta la tua logica nel codice ruby ​​/ rails, così non dovrai mai scherzare con le impostazioni esplicite dell'ID.

+0

se ho bisogno di cambiare i dati iniziali, le cose possono diventare disordinate quando si usano le migrazioni. il tuo secondo commento non ha davvero senso. i collegamenti tramite chiavi esterne verranno distrutti – Tony

+0

c = Categoria.create (materiale) p = Post.create (materiale) p.category = c Non è necessario impostare esplicitamente gli ID. Se si modificano i dati iniziali, è sufficiente creare una nuova migrazione. Molto facile. –

+0

che presuppone che le associazioni possano essere fatte al momento della creazione dell'oggetto. ecco un esempio in cui credo che la tua logica fallisca ... correggimi se sbaglio. io semina il DB con i temi del modello. user id = 1 crea id template = 2 e id tema = 4. a questo punto, un record è nel db come segue: template: id = 2, user_id = 1, theme_id = 4. ora se re-init il db, theme id = 4 ora è theme id = 10 ... e quindi il template dell'utente ha un tema errato – Tony

25

factory_girl sembra che farà ciò che stai cercando di ottenere. È possibile definire tutti gli attributi comuni nella definizione predefinita e quindi sostituirli al momento della creazione. È inoltre possibile passare un id alla fabbrica:

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

Quando viene utilizzato con falsario è possibile popolare un database molto velocemente con le associazioni senza dover pasticciare con Fixtures (bleah).

Ho un codice come questo in un'attività rake.

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

FactoryGirl è in realtà destinato a testare al posto di fixtures, ma può essere utilizzato anche per caricare materiale in produzione. Utilizzare un'attività rake con db: migrate come prerequisito per caricare tutti i dati predefiniti. Potrebbe essere necessario rendere l'attività rake abbastanza intelligente da non creare copie di dati esistenti –

+0

L'utilizzo di FactoryGirl per seed non è raccomandato, [controllare questo post] (https://robots.thoughtbot.com/factory_girl-for-seed-data). – blackbiron

24

Di solito ci sono 2 tipi di dati semi richiesti.

  • dati di base su cui il nucleo della vostra applicazione può contare. Lo chiamo semi comuni.
  • Dati ambientali, ad esempio per sviluppare l'app è utile avere un gruppo di dati in uno stato noto che possiamo usare per lavorare sull'app localmente (la risposta di Factory Girl sopra copre questo tipo di dati).

Nella mia esperienza ho sempre riscontrato la necessità di questi due tipi di dati. Così ho messo insieme a small gem that extends Rails' seeds e ti permette di aggiungere più file seme comuni in db/seeds/e qualsiasi dato seme ambientale in db/seeds/ENV per esempio db/seeds/development.

Ho trovato questo approccio è sufficiente a dare i miei dati di semi certa struttura e mi dà il potere di impostare il mio ambiente di sviluppo o messa in scena in uno stato conosciuto semplicemente eseguendo:

rake db:setup 

Fixtures sono fragili e flakey per mantenere, come sono discariche sql regolari.

21

L'utilizzo del file seeds.rb o FactoryGirl è ottimo, ma questi sono grandi rispettivamente per strutture dati fisse e test.

La gemma seedbank potrebbe offrire maggiore controllo e modularità ai semi. Inserisce le attività di rake e puoi anche definire le dipendenze tra i tuoi semi. L'elenco delle attività rake avrà queste aggiunte (ad esempio):

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 
0

Rails è dotato di un modo per seminare i dati come spiegato here.

Un altro modo sarebbe utilizzare una gemma per semina più avanzata o facile come: seedbank.

Il vantaggio principale di questa gemma e il motivo per cui lo utilizzo è che ha funzionalità avanzate quali le dipendenze di caricamento dei dati e i dati di seed per l'ambiente.

Aggiunta di una risposta aggiornata in quanto questa risposta è stata la prima su google.

Problemi correlati