Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Migrating data with rake db:migrate does not change it

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?

like image 402
Martin Macak Avatar asked May 03 '14 17:05

Martin Macak


People also ask

How rails db Migrate works?

When you run db:migrate, rails will check a special table in the database which contains the timestamp of the last migration applied to the database. It will then apply all of the migrations with timestamps after that date and update the database table with the timestamp of the last migration.

What does db Migrate do?

DB migration is moving data from one or more source platforms to another target database. There are several reasons for migrating from one database to another. For example, a business might want to save resources by switching to a cloud-based database.

How do I change migration in Rails?

5 Changing Existing Migrations You must rollback the migration (for example with bin/rails db:rollback ), edit your migration, and then run bin/rails db:migrate to run the corrected version.

What does db Migrate Reset do?

db:reset: Resets your database using your migrations for the current environment. It does this by running the db:drop , db:create , db:migrate tasks. db:rollback: Rolls the schema back to the previous version, undoing the migration that you just ran. If you want to undo previous n migrations, pass STEP=n to this task.


2 Answers

  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.

like image 161
Kirti Thorat Avatar answered Oct 19 '22 15:10

Kirti Thorat


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.

like image 3
Martin Macak Avatar answered Oct 19 '22 17:10

Martin Macak