All migration files in Rails are by default prefixed with the timestamp which serves as the version number for the migration file. For an instance a migration file with name 20160310141700_create_users.rb is prefixed with timestamp 20160310141700.

Rails maintains a table named schema_migrations which has a single column named version to store the version number of the migration files that have been already executed on DB.

Do all migration files are executed when we run rake db:migrate ?

The answer in NO.

Whenever we run the rake db:migrate it reads all the version numbers stored in DB, as well as all the version number for the files present in folder db/migrate. It then decides which are the migrations which are not yet applied on DB, and then execute only those. By this Rails ensures that each migration is applied only once. It runs change or up method in all the selected migration files.

By default rake db:migrate task also runs db:schema:dump, so that your db/schema.rb reflects the latest structure of the database.

When we have a couple of developers working on a project then they can commit there migration files in any order, since rails running on an individual system already knows which migration files have been executed on DB and which not.

So for the same reason it is not wise to modify the old migration file, instead add a new one. Because it will not be executed on systems which have already executed it earlier.

Running migrtaions upto a particular version number

Since the version numbers are timestamp, we can specify a particular version number upto which migration needs to be executed.

bin/rails db:migrate VERSION=20160310141700

If the current version number is less than 20160310141700 then above rake task will execute up method on rails migration till 20160310141700. Otherwise it will run migrations downward from current version, executing down method on all rails migration excluding 20160310141700.

If you want to look deep into source code on how it is really applied on low level, then you can look for class ActiveRecord::Migrator