Question

I am struggling with rails and db:migrate. I have a migration with this code

class SetDefaultInstallmentsForLicenses < ActiveRecord::Migration
  def up
    License.where(code: 'LEADER').each do |leader|
      puts "Modifying license #{leader.id} with code #{leader.code}"
      leader.installment_available = true
      leader.installment_number = 5
      leader.save
      puts "After save #{leader.installment_available} #{leader.installment_number}"
      leader = License.find(leader.id)
      puts "After save #{leader.installment_available} #{leader.installment_number}"
    end
  end

  def down
  end
end

After running the migration there is this output

==  SetDefaultInstallmentsForLicenses: migrating ==============================
Modifying license 3 with code LEADER
After save true 5
After save f
==  SetDefaultInstallmentsForLicenses: migrated (0.0037s) =====================

It's clearly visible that the migration was executed, record was found, changed and saved, but after reloading the record, the changes are not there. What's wrong?

Was it helpful?

Solution

  leader.save
  puts "After save #{leader.installment_available} #{leader.installment_number}"
  ==> After save true 5  

Above is only showing the value of installment_available and installment_number fields from local variable leader, it is NOT pulling the value from database. This does not mean that the fields were successfully saved in database.

  leader = License.find(leader.id)
  puts "After save #{leader.installment_available} #{leader.installment_number}"

BUT the above is fetching the record from database and clearly shows that the updates were not saved in the database.

Instead of leader.save, use leader.save!. This way if record was not saved then you will know exactly why it was not saved because of the raised exception .

UPDATE

As per OP's answer given on this question

I tried to put

License.reset_column_information

before the code and it seems to be working now. I don't have clue why this is needed here. All my other migrations seem to be working properly.

I did little bit of research what exactly License.reset_column_information did. I found Using Models in Your Migrations which says:

When using a local model, it's a good idea to call Product.reset_column_information to refresh the Active Record cache for the Product model prior to updating data in the database.

Hope this helps you to understand why License.reset_column_information was required.

OTHER TIPS

I tried to put

License.reset_column_information

before the code and it seems to be working now. I don't have clue why this is needed here. All my other migrations seem to be working properly.

Are you sure that it's been saved. I'm not. Place:

puts leader.errors.full_messages.to_sentence

after leader.save string

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top