header image


May 3rd, 2006

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/001productmigration.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!

Similar Posts:viagra online



If you liked the article, subscribe to the feed   and follow me on twitter!.


      

11 Responses to “”

  1. cremes Says:

    , 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.

  2. peter Says:

    , 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…

  3. Ruby, Rails, Web2.0 » Blog Archive » Ruby on Rails Migrations Reloaded Says:

    , [...] Ruby on Rails Migrations Reloaded [...]

  4. Jeff Rasmussen’s Healthcare IT Blog » RoR Migration Tool Says:

    , [...] Ruby on Rails Migrations 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). [...]

  5. Mike Says:

    , 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!

    , Mike

  6. peter Says:

    , 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)

    * :limit: Requests a maximum column length
       (:string, , :text, , :binary or :integer columns only)
    * :default: The column’s default value.
       You cannot explicitely set the default value to NULL.
       Simply leave off this option if you want a NULL default value.
    * :null: Allows or disallows NULL values in the column.
       This option could have been named :null_allowed.
    

    , Hope this helps.

  7. craps table Says:

    , craps table craps table

  8. 2003 lexus ls430 Says:

    , 2003 lexus ls430…

    , ha-rd-po-rn-fu-ck 2260204 Modern view of 2003 lexus ls430….

  9. bbw toy Says:

    , bbw toy…

    , ka-ka-sh-ka 2260204 Value source for bbw toy….

  10. tucci Says:

    , tucci…

    , This page contains some info about tucci…

  11. Aryk Grosz Says:

    , 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?

Leave a Reply




Bad Behavior has blocked 2401 access attempts in the last 7 days.