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
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
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
version numbers are timestamp, we can specify a particular
version number upto which migration needs to be executed.
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
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