Peter Marklund

Peter Marklund's Home

Sun Mar 29 2009 17:45:32 GMT+0000 (Coordinated Universal Time)

Upgrading from Rails 1.2.3 to Rails 2.3.2

Have you ever tried upgrading Rails from version 1 to version 2? If not, you're in for a treat. Seriously though, it's not that bad, but depending on the size of your app, the number of plugins you use, and how badly you've patched Rails, your mileage may vary.

Here are some notes from an upgrade of this little weblog app just now:

# 0. Upgrade Rails

sudo gem install rails
rails -v
# => Rails 2.3.2

# 1. Since rails:freeze:gems in 1.2.3 is not compatible with RubyGems 1.3.1 (GemRunner issue) and
#    since it doesn't know about activeresource, we'll use a fresh Rails 2.3.2 for checking out
#    the sources:

cd ~/src
rails rails23-app
cd rails23-app
rake rails:freeze:gems
# Generate app and test code to reveal some latest best practices
./script/generate scaffold categories name:string
./script/generate integration_test demo

# 2. Create a branch for the upgrade

cd ~/src/app_to_upgrade
git checkout -b rails23 # Assumes your app is in Git

# 3. Upgrade the Rails source

rm -rf vendor/rails
mv ~/src/rails23-app/vendor/rails vendor

# 4. Upgrade config/boot.rb and public/javascripts/*. Rename application.rb to application_controller.rb

rake rails:update

# 5. Get the config/initializers/* files. Make sure the session settings are right for your app.

cp -r ~/src/rails23-app/config/initializers config

# 6. Make sure your config/environment.rb and config/environments/* files are Rails 2.3 compatible.
#    Do this by comparing your versions of the files with the ones in rails23-app. Notes:
#
# - Do not use config.time_zone = 'UTC' unless your database datetime columns are in UTC
#   (see http://marklunds.com/articles/one/405)
# - You want to keep your environment.rb file fairly small by breaking parts out into
#   config/initializers/* files. 
# - ActionMailer::Base.server_settings has been renamed to ActionMailer::Base.smtp_settings

# 7. Remove/upgrade/patch any plugins that your app has that may not be Rails 2.3 compatible.
#    Some stuff has been moved out of Rails and into plugins and then you'll have to install those plugins.
#    For pagination I recommend will_paginate (http://github.com/mislav/will_paginate/tree/master).

# 8. Review any patches that you have made to Rails.

# 9. Make your tests Rails 2.3 compatible:
# - in test/test_helper.rb it's now the ActiveSupport::TestCase class that should be opened,
#   not Test::Unit::TestCase.
# - Change your unit tests to extend ActiveSupport::TestCase
# - Change your helper tests to extend ActionView::TestCase and move them to a new test/unit/helpers directory
# - Change your functional tests to extend ActionController::TestCase
# - Note that now fixtures :all is the default setting. I highly recommend this setting over
#   specifying fixtures in each test (see http://marklunds.com/articles/one/386).
#   You still have to say fixtures :all in integration tests though.
# - You may get deprecation warnings when running the tests, such as truncate now taking a hash argument etc.
#   Fix those :-)

# 10. Commit your branch in Git, merge it to master, and deploy.

As a bonus, here is a script to migrate your .rhtml view templates to the new .html.erb extension:

#!/usr/bin/env ruby
#
# change-extension <path> <from-extension> <to-extension>
#
# Command line script to recursively move all files under a certain directory from
# one extension to another. Example usage: moving all .rhtml files in a Rails app to .html.erb to adopt
# the new conventions in Rails 2.

unless ARGV.size == 3
  puts "Usage: #{$0}: <path> <from-extension> <to-extension>"
  exit -1
end
root_path, from_ext, to_ext = ARGV

MOVE_COMMAND = "git mv"
Dir[File.join(root_path, "**", "*.#{from_ext}")].each do |from_path|
  to_path = from_path.chomp(from_ext) + to_ext
  command = "#{MOVE_COMMAND} #{from_path} #{to_path}"
  puts command
  system(command)
end

There you have it! Now you can enjoy Rails 2.3.2 in all its glory!