Search code examples
ruby-on-railsmigrationrails-migrations

Creating a rails migration and and populated existing values based off of a method within a model


I have a made a change to a method that defines a specific value that I wanted to add within my database. I then created a migration to add to that value. However the problem that I having is that with what i've done, it populates any of the new values, yet I have a few hundred older values that need to be populated and i've been having trouble getting those populated.

Here is what my code looks like, this is a model called OrderTransactions

def set_pricing_amounts
  pricing_service = PricingService.new(visit: visit)
  self.base_price = pricing_service.base_price
end

The base_price is what I need, which is ultimately created within the PricingService. I don't think I need to display any information around what is in the PricingService (if I do let me know)

My migration at first was like this:

class AddedBasePriceToOrderTransactions < ActiveRecord::Migration
  def change
    add_column :order_transactions,  :base_price, :integer
  end
end

I've tried something along the lines of this

OrderTransaction.all.each do |product|
  product.update_attributes!(:base_price => base_price)
end

This updates all of my order transactions, but gives them all a value of 1.....which is not correct.

i've also tried

OrderTransaction.all.each do |zg|
  zg.update_attributes(base_price: PricingService(:visit, visit).base_price)
end

I feel like this may be a closer approach, but the visit is not recognized within the migration and so I cannot get it to be recognized.

If anyone could take a look at this, I would really appreciate it!


Solution

  • If the set_pricing_amounts is a public method you could do this:

    OrderTransaction.all.each do |product|
      product.set_pricing_amounts
      product.save!
    end
    

    (Or if it's private, you can do product.send(:set_pricing_amounts) instead)

    If you want to call the pricing service, then this should work:

    OrderTransaction.all.each do |order|
      order.update_attributes base_price: PricingService.new(visit: order.visit).base_price
    end
    

    Side note: if you've got a lot of records to migrate, you should look at using OrderTransaction.all.find_each instead of OrderTransaction.all.each, but that's just a tip and not directly related to the questino.