How does Rails know if a migration has previously run? I ran this question by a few colleagues at my nine-to-five yesterday, and they all were uncertain on how Rails achieved it. We all thought that the schema.rb file associated to your project had something to do with it; however, we were mistaken, and it does not. The schema.rb is for constructing a new database from scratch, or for an existing project to know the up-to-date version of your Rails application’s database schema. At my place of employment, we use the schema.rb to deploy new servers that run our application without having to invoke all of the active record migrations associated our project; doing so would take too much time and potentially cause errors that would render the database unusable.
Now back to the original question. I checked Rails Guides, but they only presented me with vague information regarding it. So I turned to Stack Overflow, which led me in the right direction.
Rails determines what active record migrations has been previously run by the hidden table that all Ruby on Rails projects have in their database schema: schema_migrations. schema_migrations contains a single column named “version”. In that column it contains the timestamps that are preappended to the name of your migrations that you have created, i.e., 20110705043737, which is attached to a migration that this weblog previously ran 20110705043737_create_posts.rb. Each timestamp in schema_migration version column represents migrations that have previously invoked. Below you can see the migrations that have invoked for the weblog you are currently reading.
Output below is from the postgres console:
select * from schema_migrations;
version ---------------- 20110623095018 20110628001857 20110702042423 20110705042856 20110705043737 (5 rows)
To illustrate, imagine you have created a migration to add a column to table called “20120526043737_add_hyperlink_to_pages.rb” and execute rake db:migrate in the terminal. Rails will search for the time stamp 20120526043737 in schema_migrations; not find a version with an identical time stamp; execute the migration which adds hyperlink to pages; add that time stamp to schema_migrations so the next time you run rake db:migrate it will not execute that migration again, and then finally update your applications schema.rb, which makes it up to date. On the opposite end of the spectrum, imagine if Rails found the migration time stamp in schema_migrations; it would not invoke the migration and move on the next migration, if there is one.
Hopefully, this post gets properly indexed by Google and is beneficial to someone who wonders how Ruby on Rails Active Record magic works.