2012-01-19 10 views
12

Ho un modello chiamato spedizioni. Ho aggiunto alcune colonne alla tabella delle spedizioni e ci sono alcune colonne che dovrebbero essere calcolate prima del salvataggio. Quindi ora devo modificare ogni record e fare clic su Aggiornamento in modo che le nuove colonne possano calcolare e aggiungere i dati.Rails 3. Come eseguire un'azione di salvataggio su tutti i record?

Quindi esiste un modo per eseguire un salvataggio globale su tutti i record di spedizione in modo che i dati possano essere aggiunti?

before_save :default_values 
    def default_values 
    self.volume = 1 unless self.volume 
    self.kilograms = 1 unless self.kilograms 
    self.status = "Open" if self.status.blank? 
     if self.mode == "Air" 
     self.estimated_transit_time = self.etd_origin + 7.days 
     self.eta_place_of_delivery = self.etd_origin + 7.days 
     else 
     self.estimated_transit_time = self.etd_origin + (Place.find_by_city(self.place_of_loading).transit_time).days 
     self.eta_place_of_delivery = self.etd_origin + (self.estimated_transit_time).days 
     end 
    end 

risposta

1

Si può fare un metodo come questo:

def self.save_all 
    Shipment.all.each { |shipment| shipment.save! } 
end 

Poi basta chiamare:

Shipment.save_all 
+0

ottengo 'SystemStackError (livello di stack troppo in profondità):' ma se corro 'Shipment.all.each {| spedizione | shipment.save!} 'nella console funziona. Grazie! :) – leonel

13

caricare i dati per lotto. Mai carico di tutto in una volta

Shipment.find_each(:batch_size => 1000) do |shipment| 
    shipment.save! 
end 

Poi, quando si deve calcolare alcuni campi dopo una migrazione o qualcos'altro. Semplicemente aggiungi questo lavoro alla tua migrazione.

+3

Attenzione a condividere il motivo per utilizzare batch anziché Model.all.each {| mdl | mld.save!}? –

+7

@ affinities23 Naturalmente! Model.all caricherà tutti i record contemporaneamente. Ciò funzionerà correttamente se si dispone di una piccola quantità di record, ma diventerà più lento e lento e alla fine si interromperà se tutti i record non possono essere memorizzati nella memoria allo stesso tempo. find_each verrà caricato per batch (non più di 1000 record caricati in memoria nel mio esempio) e ciò impedirà il problema appena descritto. – basgys

34

uno di linea:

Shipment.find_each(&:save) 
+9

Tutte queste soluzioni effettuano n chiamate al database. Sarebbe più interessante effettuare solo 1 chiamata come "update_all' per l'aggiornamento della raccolta. –

Problemi correlati