Migrations do not simply show the state of the database schema.
They define the transitions from one state to another.
In a comment to cam's post, you said having the schema in the model would do the same thing, if you had the model's source stored in a VCS, you could look up the previous versions of the schema.
Here is why that is not equivalent to migrations:
Schema Version 1
string :name
string :password
string :token
Schema Version 2
string :username
string :displayname
string :password
string :token
So, what did I do here? What happened to "name"? Did I rename it to username? Or maybe I renamed it to displayname? Or did I drop it entirely?
You don't know. There's no way to tell. You only see the "before" and "after" of the schema. You don't see the transition.
Let's instead look at what I really did with this migration:
class UpdateNameFields < ActiveRecord::Migration
def self.up
rename_column :users, :name, :username
add_column :users, :displayname
User.update_all("displayname = username")
end
def self.down
remove_column :users, :displayname
rename_column :users, :username, :name
end
end
See, I had been using "name" for usernames. But you wouldn't be able to tell that without the migration here. Plus, in an effort to not have my new displayname column be blank on all my existing records, I have seeded it with everyone's existing usernames. This lets me gently introduce this new feature - I can use it and know that existing records aren't going to just see a blank field.
Note that this is a trivial example. Because it was so trivial, you could take a guess that it was one of a couple possible options. But had it been a much more complex transition, you simply would not know.
Transitions from one schema to another can involve a more than just adding/deleting/renaming columns. I gave a little example above in my User.update_all. Whatever code you might need to execute to migrate data to the new schema, you can put in the migration.
When people say migrations are about "versioning the database", they don't just mean versioning the snapshot of the schema. They mean the ability to move between those schema states, and triggering all of the actions involved in going from one state to another.