Topic: Rails Migrations for beginners
In the "old days" of Rails (before version 1.0), most people created the databases their apps use directly in SQL, or by using tools like MySQLFront to help them along. This approach has its problems though: how do you know what has changed in the data model between versions of your app? Why do we have to use SQL here when ActiveRecord does a great job of abstracting that away for us? The answer to this came in the form of ActiveRecord migrations. With migrations, you create your database schema in Ruby instead of SQL DDL. If you want to change your data model, say by renaming a column or adding a table, you just write another migration class to do it. Your database keeps track of versioning for you, and you can easily see what changed in the data model just by reading the migration code. It's great, and if you want to learn how to use migrations in your Rails apps, then read on.
How to use migrations:
First you use the Rails generator to create your migration. You can generate just the migration, or you can do it by generating a model, which will also give you a migration file.
$ ./script/generate migration add_posts
This will create something like 001_add_posts.rb in the /db/migrate folder of your app.
Then you create the table like so:
class AddPosts < ActiveRecord::Migrationdef self.up
create_table "posts" do |t|
t.column "title", :string
t.column "content", :text
end
enddef self.down
drop_table "posts"
endend
The self.up method runs when you run the database migration via rake. Self.down runs when you tear down the database.
If you need to update the table later (say, adding a user_id column to track which post belongs to a user), you would generate another migration to add the column:
$ ./script/generate migration add_user_id_to_posts
Then you'd add your column in /db/migrate/002_add_user_id_to_posts.rb:
class AddUserIdToPosts < ActiveRecord::Migrationdef self.up
add_column "posts", "user_id", :integer
#optional, but it could help depending on your site
add_index "posts", "user_id"
enddef self.down
end
end
When you want to actually generate your database (be sure your information for database.yml is correct!), run rake to migrate the database:
$ RAILS_ENV=development rake db:migrate
(setting RAILS_ENV may not be necessary depending on how your environment is set up).
There you go! You have a database with all the table and column information you wrote in. Wasn't that easy?
Don't think of each migration file as a table, think of it as a change to the data model. You can create more than one table in each migration, or you can just add/remove columns, indices, etc.
Migrations act as version control for your database changes and they're extremely useful.