Reputation: 3831
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?
Upvotes: 5
Views: 936
Reputation: 53028
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.
Upvotes: 6
Reputation: 3831
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.
Upvotes: 3
Reputation: 1219
Are you sure that it's been saved. I'm not. Place:
puts leader.errors.full_messages.to_sentence
after leader.save
string
Upvotes: 0