Domanda

Ho apparecchi con dati iniziali che devono risiedere nel mio database (paesi, regioni, vettori, ecc). Ho un compito rake db: seme che saranno alla base di un database

.
namespace :db do
  desc "Load seed fixtures (from db/fixtures) into the current environment's database." 
  task :seed => :environment do
    require 'active_record/fixtures'

    Dir.glob(RAILS_ROOT + '/db/fixtures/yamls/*.yml').each do |file|
      Fixtures.create_fixtures('db/fixtures/yamls', File.basename(file, '.*'))
    end
  end
end

Sono un po 'preoccupato perché questo compito asciuga il mio database pulito e carica i dati iniziali. Il fatto che questo è ancora possibile fare più di una volta sulla produzione spaventa la merda di me. È questo normale e posso solo essere prudenti? O la gente di solito proteggono un compito come questo in qualche modo?

È stato utile?

Soluzione

Dati semina con i dispositivi è una pessima idea.

Fixtures non vengono convalidati e dal momento che la maggior parte degli sviluppatori Rails non usano vincoli del database questo significa che si può facilmente ottenere dati non validi o incompleti inseriti nel database di produzione.

Infissi anche impostare strane id chiave primaria per difetto, che non è necessariamente un problema, ma è fastidioso da lavorare.

Ci sono un sacco di soluzioni per questo. Il mio preferito è un compito rastrello che esegue uno script di Ruby che utilizza semplicemente ActiveRecord per inserire i record. Questo è ciò che Rails 3 farà con db:seed, ma si può facilmente scrivere questo da soli.

I completano questo con un metodo aggiungo a ActiveRecord :: Base chiamato create_or_update. Utilizzando questo posso eseguire lo script seme più volte, aggiornando vecchi dischi invece di lanciare un'eccezione.

ho scritto un articolo su queste tecniche un po 'indietro chiamato dati semi Loading .

Altri suggerimenti

Per la prima parte della tua domanda, sì, avevo appena messo un po 'di precauzione per l'esecuzione di un compito come questo in produzione. Ho messo una protezione come questo nel mio bootstrap / compito seeding:

task :exit_or_continue_in_production? do
  if Rails.env.production?
    puts "!!!WARNING!!! This task will DESTROY " +
         "your production database and RESET all " +
         "application settings"
    puts "Continue? y/n"
    continue = STDIN.gets.chomp
    unless continue == 'y'
      puts "Exiting..."
      exit! 
    end
  end
end

Ho creato questo succo per un po 'di contesto.

Per la seconda parte della domanda - di solito si vuole veramente due cose: a) molto facilmente semina il database e impostare l'applicazione per lo sviluppo, e b) bootstrapping l'applicazione sul server di produzione (come: l'inserimento di utente amministratore, la creazione di cartelle applicazione dipende, ecc).

mi piacerebbe utilizzare apparecchi per la semina in fase di sviluppo - tutti dalla squadra vede quindi gli stessi dati in app e che cosa è in app è coerente con ciò che è in test. (Di solito mi avvolgo rake app:bootstrap, rake app:seed rake gems:install, ecc in rake app:install modo che tutti possano lavorare sul app appena la clonazione del pronti contro termine e l'esecuzione di questa operazione.)

Mi piacerebbe però mai usare apparecchi per la semina / bootstrap sul server di produzione. db/seed.rb Rails' è veramente bene per questo compito, ma è possibile, naturalmente, mettere la stessa logica nel vostro compito rake app:seed, come altri hanno sottolineato.

Rails 3 risolverà questo per voi utilizzando un file seed.rb.

http://github.com/brynary/rails/commit/4932f7b38f72104819022abca0c952ba6f9888cb

Abbiamo creato un mucchio di buone pratiche che usiamo per i dati di semina. Contiamo molto sulla semina, e abbiamo alcuni requisiti unici in quanto abbiamo bisogno di seminare i sistemi multi-tenant. Ecco alcune best practice che abbiamo usato:

  1. Fixtures non sono la soluzione migliore, ma ancora devono memorizzare i dati di semi in qualcosa di diverso da Ruby. codice Ruby per la memorizzazione dei dati di semi tende a diventare ripetitivo, e la memorizzazione dei dati in un file di pagina ea un blocco significa che è possibile scrivere codice generico per il trattamento dei semi in modo coerente.
  2. Se avete intenzione di aggiornare potenzialmente semi, utilizzare una colonna marcatore nome simile code per abbinare il file vostri semi ai dati effettivi. Mai fare affidamento su ids essere coerente tra gli ambienti.
  3. Pensate a come si desidera gestire l'aggiornamento dei dati di semi esistenti. C'è qualche possibilità che gli utenti hanno modificato questi dati? Se è così, si dovrebbe mantenere le informazioni dell'utente e non viene sostituito con i dati di semi?

Se siete interessati in alcuni dei modi in cui noi facciamo semina, li abbiamo confezionato in una gemma chiamata SeedOMatic .

Come circa appena eliminare l'attività dal tuo server di produzione una volta che avete seminato il database?

Ho appena avuto un'idea interessante ...

Che cosa succede se si è creato \ DB semi \ \ e aggiunto i file di migrazione in stile:

file: 200907301234_add_us_states.rb

class AddUsStates < ActiveRecord::Seeds

  def up
    add_to(:states, [
      {:name => 'Wisconsin', :abbreviation => 'WI', :flower => 'someflower'},
      {:name => 'Louisiana', :abbreviation => 'LA', :flower => 'cypress tree'}
      ]
    end
  end

  def down
    remove_from(:states).based_on(:name).with_values('Wisconsin', 'Louisiana', ...)
  end
end

alternativamente:

  def up
    State.create!( :name => ... )
  end

Ciò permetterà di eseguire le migrazioni e semi in un ordine che avrebbe permesso loro di coesistere pacificamente più.

pensieri?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top