2012-01-19 2 views
12

У меня есть модель под названием поставки. Я добавил несколько столбцов в таблицу отправлений, и есть несколько столбцов, которые должны быть рассчитаны до сохранения. Поэтому теперь мне нужно отредактировать каждую запись и нажать обновление, чтобы новые столбцы могли вычислять и добавлять данные.Rails 3. Как выполнить действие сохранения во всех записях?

Итак, есть способ выполнить глобальную экономию на всех отгрузках, чтобы данные можно было добавить?

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 

ответ

1

Вы можете сделать метод как это:

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

Тогда просто позвоните:

Shipment.save_all 
+0

Я получаю 'SystemStackError (уровень стека слишком глубоко):' но если я бегу 'Shipment.all.each {| отгрузку | shipment.save!} 'в консоли он работает. Благодаря! :) – leonel

13

Загрузите данные по партии. Никогда нагрузка сразу

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

Тогда, когда нужно вычислить некоторые поля после миграции или что-то другое. Просто Добавить эту работу в вашу миграцию.

+3

Упоминайте, почему использовать партии, а не Model.all.each {| mdl | mld.save!}? –

+7

@ affinities23 Конечно! Model.all будет загружать сразу все записи. Это будет очень хорошо, если у вас будет небольшое количество записей, но будет медленнее и медленнее, и в итоге выйдет из строя, если все записи не смогут вписаться в память одновременно. find_each будет загружаться пакетом (не более 1000 записей, загруженных в память в моем примере), и это предотвратит проблему, которую я только что описал. – basgys

34

Один лайнер:

Shipment.find_each(&:save) 
+9

Все эти решения делают n вызовов в базе данных. Было бы интереснее сделать только один вызов типа 'update_all' для обновления коллекции. –

Смежные вопросы