#83
Dec 09, 2007

Migrations in Rails 2.0

Migrations are now sexy in Rails 2.0! In this episode we will take a look at these improvements and the related rake tasks.
Tags: rails-2.0
Download (11 MB, 5:31)
alternative download for iPod & Apple TV (7.1 MB, 5:31)
rake db:create
rake db:create:all
script/generate model task name:string priority:integer
script/generate migration add_description_to_task description:string
script/generate migration remove_description_from_task description:string
# migrations/001_create_tasks.rb
create_table :tasks do |t|
  t.string :name
  t.integer :priority, :position
  t.timestamps
end

RSS Feed for Episode Comments 25 comments

1. nicolash Dec 10, 2007 at 01:59

wouldn't it be more consequent to write:
script/generate migration add_description_to_tasks description:string -
so tasks instead of task?
(works also) - as we have create_tasks (in plural)...
(same for remove obviously).


2. Adam Dec 10, 2007 at 02:06

"Sexy" is my new least favourite coding buzzword... but good to see the new Rails 2.0 migrations keeping things so damn sexy ;) And the rake tasks which will save me jumping into phpMyAdmin for each new db not to mention the neat generators... as they say: if you have to do something twice - automate it!


3. DAddYE Dec 10, 2007 at 03:32

[OT]Hello Rayan, did you receive my mail? Because some time my host reject them.

Thanks[/OT]


4. Tony Petruzzi Dec 10, 2007 at 05:12

Ryan,

You screen casts are the best. I've learned so much from them as I'm attempting to move from ColdFusion to Rails.

There are only two things that are stopping me from making the move and maybe you can shed some light on them and they could be cool ideas for future screen casts.

First - In CF creating a PDF from a webpage is dead easy using the CFDOCUMENT tag. I've watch episode 78 on creating PDFs but it was very clunky at best. Plus you couldn't just pass in a variable containing the HTML to render and have it print out in the PDF. Do you know of any plugin or way to do this?

Second - Database views are never mentioned in any related to rails. Sometimes database views can be invaluable. Take this situation for instance: Suppose you have to get data from two different databases and mash them together. Out of the box ActiveRecord doesn't support multiple databases (though there are plugins that handle this). What you could do however is write a view that grabs the data from both databases and mashes it together.

So my question is: Is there anyway to tell ActiveRecord to create a class file for the view?


5. Tony Petruzzi Dec 10, 2007 at 06:34

@Chris,

Thank you for the links, they were extremely helpful. Do you have any link about working with database views and ActiveRecord?

Also, can anyone out there answer the PDF question?


6. andy Dec 10, 2007 at 08:33

this didn't show up in my newsreader - am I the only one?

kinda freaked me out a little bit since I'm something of a railscast junkie.


7. andy Dec 10, 2007 at 08:34

ah!! I hit submit and my newsreader lights up, it was just me.

sorry


8. Trent Ogren Dec 10, 2007 at 09:02

@Tony

Just to assure you that you're making the right choice: Indeed.com is showing that there are now more Ruby jobs than there are Cold Fusion jobs:
http://prfsa.com/post.rhtml?title=ruby-passes-coldfusion-at-indeed


9. crzivn Dec 10, 2007 at 14:03

@Tony
One way to work with pdf is to use the iText java library with a ruby java bridge.
http://blog.codeinmotion.com/index.php/2006/12/22/pdf-generation-in-ruby-on-rails/


10. burmaja Dec 11, 2007 at 06:05

Is there any rake task or something just to export migration to script in Rails 2.0?

Tnx


11. Ryan Bates Dec 11, 2007 at 10:06

@nicolash, good point. I think pluralizing it makes sense.

@DAddYE, yep! I did receive the email, but I haven't had time to respond to it yet. Things have been busy here.

@burmaja, do you mean a way to convert a migration to SQL? I don't know of a rake task that does this, but there's probably some way to write one. Haven't looked into it.


12. Joshua Garner Dec 11, 2007 at 12:59

Hey,

You can also use references eg,

t.references :post, :user

and it will create integer foreign keys

post_id
user_id

Cheers


13. burmaja Dec 12, 2007 at 00:14

@Ryan, Yes, I ment exactly that. It is very useful if your DB admin's don't allow DDL as it is case in my bank. So procedure is to give them script, they check it and then they execute it. I have to find the way to make such a rake task.


14. burmaja Dec 12, 2007 at 02:56

If someone is interested, tnx to dr. google and Rich's code at http://www.justatheory.com/computers/databases/postgresql/rails_and_slony.html, here's my rake task that scripts migration into migration.sql file. Place the code in lib/tasks/whatever.rake and than call rake db:script_migration. However, this scrips all migrations from 0.

namespace :db do
  desc "Script SQL from migration"
  task :script_migration => :environment do
    ActiveRecord::Base.connection.class.class_eval do
      # alias the adapter's execute for later use
      alias :old_execute :execute
      
      # define our own execute
      def execute(sql, name = nil)
        # check for some DDL and DML statements
        if /^(create|alter|drop|insert|delete|update)/i.match sql
          File.open('migration.sql', 'a') { |f| f.puts "#{sql}\n" }
        else
          # pass everything else to the aliased execute
          old_execute sql, name
        end
      end
    end
    
    # create or delete content of migration.sql
    File.open('migration.sql', 'w') { |f| f.puts "-- Script created @ #{Time.now}" }
    # invoke the normal migration procedure now
    Rake::Task["db:migrate"].invoke
  end
end


15. Mike Dec 15, 2007 at 18:14

Thanks for making these. I like how you are focusing on features of Rails 2.0. Please continue this theme.

Seeing the new features and changes in action is very helpful and useful for me, especially since all the books cover mostly Rails 1.2.5.


16. john Jan 02, 2008 at 19:45

Here you've done:
add_column_to_table, but elsewhere they say do:
AddColumnToTable

in the migration script.

Also, could you discuss references keyword when used in this situation. It doesn't seem to work in conjuction with the add/remove migrations, but does work in the initial scaffold command.


17. Chase Feb 23, 2008 at 17:42

Any idea what this error is about?

-- create_table(:participants)
rake aborted!
private method `file' called for #<ActiveRecord::ConnectionAdapters::TableDefinition:0x1a7500c>


18. Chase Feb 24, 2008 at 04:24

stupid transposition of column type and name. sorry.


19. Danny Mar 30, 2008 at 04:48

Thanks for your Railscasts and the latest one's on Rails 2.0! Greets, Danny


20. Brian Doll Apr 02, 2008 at 10:58

Thanks a million for your railscasts. Worth far more than their weight in bytes!

I wanted to point out a subtle feature in these migration generate tasks that may be useful to folks:

As Ryan noted, the migration name is important, primarily in determining if we are adding/removing and to which table.

However, the column that you are adding is less significant. Take the following example:

script/generate migration add_stuff_to_tablename foo:text bar:text baz:text

This will create a migration that adds foo, bar and baz to the table "tablename" as expected, even though those fields are not identified in the migration name.

cheers,
b


21. jg May 09, 2008 at 06:20

I've tried both add_columnname_to_table and AddColumnnameToTable and have gotten the following error messages:

"Couldn't find 'add_dateavailable_to_product' generator"

"Couldn't find 'adddateavailabletoproduct' generator"


22. jg May 09, 2008 at 06:39

My introduction to Rails thus far has been a bit of a disaster. All this talk about agile development and here I am stuck at something so trivial.

Is there any way to do things the old way? To me, it makes much more sense to do the scaffolding based off an existing schema. Speaking without knowing if they have or not, but they should have kept the old functionality. It really didn't make any sense to remove it.


23. Brian Doll May 22, 2008 at 19:32

jg,

It would be helpful to see the full command that you are issuing that is giving you errors, but I'm guessing your not providing the generator script the initial argument.

Correct:
script/generate migration add_stuff_to_table

Incorrect:
script/generate add_stuff_to_table

Make sense?


24. kino May 23, 2008 at 01:56

Metaphysics, in accordance with the principles of our faculties, is the key to understanding the manifold; however, our knowledge exists in our understanding.


25. Melvin Ram Aug 20, 2008 at 12:42

Does this allow for renaming of columns? Something like this:

script/generate migration rename_description_to_task teaser:string

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player