Ruby-on-rails – How does Rails keep track of which migrations have run for a database


According to Rails doc:

"Active Record tracks which migrations have already been run so all you have to do is update your source and run rake db:migrate."

How does ActiveRecord actually do this? Where does Active Record store the data?

I suspect this might be stored in the database itself? In a table somewhere.

On my development machine, I ran all the migrations. Then I copied the production database over using mysqldump. Then I ran "rake db:migrate:status", it shows correctly the migrations that need to run on the production database.

I used to think that ActiveRecord keeps track of the last migration run using the timestamp. But I think this is not true because ActiveRecord correctly runs the "older" migrations merged in from another code branch.

Could someone with inside knowledge of this elaborate?

Best Solution

Rails creates a table in your database called schema_migrations to keep track of which migrations have run.

The table contains a single column, version. When Rails runs a migration, it takes the leading digits in the migration's file name and inserts a row for that "version", indicating it has been run. If you roll back that migration, Rails will delete the corresponding row from schema_migrations.

For example, running a migration file named 20120620193144_create_users.rb will insert a new row with a version of 20120620193144 into the schema_migrations table.

You are free at any point to introduce migrations with earlier versions. Rails will always run any new migrations for which there is not a corresponding row in schema_migrations. The leading digits don't have to be a timestamp, you could call your migration 001_blah.rb. Earlier versions of Rails used this format, and used sequential numbering for newly generated migrations. Later versions have switched to timestamps to help prevent multiple developers from independently generating migrations with the same number.

Related Question