2012-01-19 10 views
12

Tengo un modelo llamado envíos. Agregué algunas columnas a la tabla de envíos y hay algunas columnas que se supone deben calcularse antes de guardar. Así que ahora tengo que editar cada registro y presionar actualizar para que las nuevas columnas calculen y agreguen los datos.Rails 3. ¿Cómo realizar una acción de guardado en todos los registros?

¿Existe alguna manera de realizar un guardado global en todos los registros de envío para que se puedan agregar los datos?

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 

Respuesta

1

Puede hacer un método como este:

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

A continuación, sólo llaman:

Shipment.save_all 
+0

obtengo 'SystemStackError (nivel demasiado profundo):' pero si corro 'Shipment.all.each {| envío | shipment.save!} 'en la consola funciona. ¡Gracias! :) – leonel

13

cargar sus datos por lotes. Nunca carga a la vez

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

Entonces, cuando usted tiene que calcular algunos campos después de una migración o alguna otra cosa. Simplemente agregue este trabajo a su migración.

+3

Cuide compartir el motivo para usar lotes en lugar de Model.all.each {| mdl | mld.save!}? –

+7

@ affinities23 Por supuesto! Model.all cargará todos los registros a la vez. Esto funcionará bien si tiene una cantidad pequeña de registros, pero se volverá cada vez más lenta y eventualmente se romperá si todos los registros no pueden caber en la memoria al mismo tiempo. find_each se carga por lotes (No más de 1000 registros cargados en la memoria en mi ejemplo) y esto evitará el problema que acabo de describir. – basgys

34

Un forro:

Shipment.find_each(&:save) 
+9

Todas esas soluciones hacen n llamadas a la base de datos. Sería más interesante hacer solo 1 llamada como 'update_all' para la actualización de la colección. –

Cuestiones relacionadas