The migration tool allows you to define changes to your database schema with Ruby code. It allows you to add new features, tables and columns to your database schema in an incremental and reversible way. In contrast to other development strategies, in which an entire application needs to be planned and implemented before it's in a workable state, typical Ruby on Rails applications are built in a number of phases. Each phase implements a new subsystem or feature. While if an entire application is planned in detail, the whole database schema can be written from the start, many Ruby on Rails applications details haven't been fleshed out from when RoR development began.
Just like all other components of a Rails application, migration files are generated using a generator script. To generate a new migration, you'll need to run the migration generator. It takes a single argument, which should be a descriptive name of what the migration will do. For example, if you're going to add a users table, you could pass add_users_table as an argument. Here is an example of how to run the migration generator.
script/generate migration add_users_table
Once run, the generator will place a new file in db/migrate. This file will have a filename of 002_add_users_table.rb. Your file will be named similarly, based on what your migration does. Since migrations can be both done and undone, Rails must keep track of the databases' current migration version, so the number at the beginning of the file is the migration number. The next migration you generate after this one will have 003 at the beginning of the filename. When first generated, a migration file will be almost empty and look something like this.
class CreateUsersTable < ActiveRecord::Migration def self.up end def self.down end end
As you can see, the script is mostly empty. The class name of the migration class is CreateUsersTable (which you specified when you ran the generator) and it has two methods: up and down. The up method adds new tables and columns to the database and is run when you migrate to this version from an earlier version. The down method, on the other hand, is run when you downgrade the database, taking it to a lower version number of the migration. It will undo everything the up method did, including removing all columns and tables that were created.
The Migrations Meta-Language
Migrations use a meta-language to make the scripts look somewhat like a database schema. These scripts are compact and don't contain any unnecessary information, making them easier to read for future reference and easier to write, since there is significantly less typing involved. Following Ruby on Rails' "most common use" philosophy, which states that no parameters need to be given if you're using the most common set of parameters, most parameters are hidden in migration scripts. In fact, many migration files are simply a list of column names and types without any parameters at all.
Using the Migrations Meta-Language
In this example of a migration script, the up method is used to create a users table. A user has a username, a password and timestamps. The timestamps are special columns maintained by Rails-- the created_at column stores the date and time a user was created and the updated_at column stores the date and time when the user's username or password was last modified. The down method is used to clean up all modifications to the database by dropping the users table.
class CreateUsersTable < ActiveRecord::Migration def self.up create_table :users do|t| t.string :username t.string :password t.timestamps end end def self.down drop_table :users end end
Migrations are run as a rake task. In its simplest form, the command rake db:migrate runs all the migrations necessary to bring the database to the most recent version. For example, if you've run the 001_add_users_table.rb migration and there are now two new migrations: 002_create_posts_table.rb and 003_create_comments_table.rb. The db:migrate task will run the migrations in order, running the 002 migration script first and then the 003 script, in order to bring the database to the most recent version.
You can also use the rake task to migrate the database forward or backward to a specific version. For instance, if the two new posts and comments tables didn't work as expected and need to be removed, you can migrate the database back to version 1 with this command: rake db:migrate VERSION=1. This rake task will run, in reverse order, the down methods for each migration. In other words, it will run the down method of 003_create_comments_table.rb which will drop the comments table, then the down method of 002_create_posts_table.rb which will drop the posts table.