Although migrations are a very cool feature of Ruby on Rails, they are not covered in any of the basic books on RoR i have encountered so far (Agile Web Development with Rails, Ruby for Rails Programmers).
Update: Check out my recent post: Ruby on Rails Migrations: Reloaded for an update.
Both these books are using an ‘in medias res’ style approach – they guide the reader through the essential features of Rails by building a web app from scratch. The models in the examples are creaed in SQL rather than with migrations. Let’s examine the difference on a simple example, taken from AWDwR. (Further I am assuming that you have generated a rails application, a development database for the application and the DB connection settings (database.yaml) are correct.)
The classic way: SQL DDL
Create the sql file, create.sql:
drop table if exists products; create table products ( id int not null auto_increment, title varchar(100) not null, description text not null, image_url varchar(200) not null, price decimal(10,2) not null, primary key (id) );
After this, you can create the table with:
mysql name_of_your_DB < create.sql
You are now ready to generate your model.
Doing the same with migrations
In your rails app directory, issue the following command:
ruby script/generate migration ProductMigration
then open the file db/migrate/001_product_migration.rb and edit it. To achieve the same result as in the SQL example, the file should look like this:
class ProductMigration < ActiveRecord::Migration
def self.up create_table :products do |table|
table.column :title, :string, :limit => 100, :null => false table.column :description, :text, :null => false table.column :image_url, :string, :limit => 200, :null => false table.column :price, :float, :null => false end end def self.down drop_table :products end end
Run the migration wit the following command:
rake migrate [VERSION=version_number]
And you achieved the same result as with the first method!
That's very nice, but...
Well, if the only purpose of migrations would be solely the possibility to write Ruby code instead of SQL, even this would be enough for me to go for them. However, i have to admit that this alone would be a rather feeble argument. The good news is that it is not! There is much more to migrations than writing Ruby code:
- Migrations are DB agnostic - The 'write once, use everywhere' principle really works here!
- You don't have to think about obscure SQL specific things anymore - let Rails handle them for you! (OK there are some really complicated things, but fortunately they are adressed by some great books like Rails Recipes, code snippets like Migrate Plus, and I believe that by the Rails team, too.)
- You can change the database as much as you want, and the data you have already there is not affected.
- You get very effective versioning: track changes, concurrent versions, upgrade/downgrade your schemas easily!
- You can generate DB schemas from migrations.
- And possibly much much more... I am a newbie too! 😉
In my oppinion, judging based on the Rails mailing list discussions, migrations are accepted more and more as the definitve way of creating, maintaining, versioning your DB models - so everybody considering serious Rails development should give them a look!
Your 3rd bullet point isn’t necessarily true. If you use migrations to backout to an earlier version which may entail dropping columns or entire tables, then the data in those columns/tables will disappear too. There isn’t any way to get it back unless you specifically save it off within the migration self#down method.
Minor nitpick, but I thought it worthy since we don’t want to attribute superpowers to migrations when it isn’t warranted.
Thanks for the comment, cremes!
I am in the process of learning migrations (and Rails) so i am happy to hear any comments/corrections.
This blog reflects my observations during learning rails, so it is definitely not an attempt for aÂ ‘The guru has spoken’ style stuff, but rather an ‘Everything is new to a newborn baby’ style collection of experiencesÂ 😉
I have just bought AWDwR – which uses migrations from the beginning – and also waiting for Rails Recipes paperback, so hopefully i will improve my (migrations) skills significantly in the future…
Pingback: Ruby, Rails, Web2.0 » Blog Archive » Ruby on Rails Migrations Reloaded
Pingback: Jeff Rasmussen’s Healthcare IT Blog » RoR Migration Tool
Quick question from a newbie – where can I find a list of the the values/ datatypes for all my options when creating tables (i.e. :string, :limit, :datetime). I am sure it is in the api, but just can’t think of the right terminology to look it up under. I actually have the first version of Agile Web 🙁
Any help would be greatly appreciated – thanks!
Well, as for the types, the possible values are:
Fixnum -> int, integer
Float -> decimal, numeric, float, double
Date -> interval, date
String -> blob, clob, text, char, varchar, string
Time -> datetime, time
(On the left side is the Ruby object, on the right the equivalent SQL)
AFAIK, tha available options are: (cut’n’ paste from the API)
Hope this helps.
craps table craps table
Pingback: 2003 lexus ls430
Pingback: bbw toy
You said that the migration does the same thing as the sql statements. When I use “:float” it doesn’t truncate the decimals to two places like you wanted to in your first example. How do you get migrations to do that?
These are in fact great ideas in about blogging.
You have touched some good factors here. Any way keep up wrinting.
Michael Kors Outlet
Occasionally you will make a mistake when writing a migration. If you have already run the migration, then you cannot just edit the migration and run the migration again: Rails thinks it has already run the migration and so will do nothing when you run