2010-09-09

Upgrading to Rails 3

Introduction

This post documents the steps I took to upgrade from Rails 2.3.8 to Rails 3.0.0 on Mac OS X 10.5.8 with Ruby 1.8.7.

The Steps

I started with these guides: Part 1, Part 2, Part 3.

I followed the instructions in Part 1 to use Ruby 1.9.2, but I had problems using Ruby 1.9.2, so I used Ruby 1.8.7 instead.

Factory_girl failed to install, so I installed factory_girl_rails instead. [reference]

Subdomain-fu failed to install, so I installed nhowell's version of subdomain-fu instead. [reference]

Date and time format configuration changed in Rails 3. [sample]

Authlogic authenticates_many failed with Rails 3. I used authenticates_many :user_sessions, :find_options => { :limit => 1 } to workaround this. [reference]

Webrat failed with Rails 3, so I used Capybara instead. [reference]

Since my application uses subdomains, I assigned a value to Capybara.default_host to get my tests to pass. [reference]

Authlogic failed with Rails 3, so I used odorcicd's rails3 branch instead. [reference]

I needed to call html_safe() for all return values from my custom form builder method. [sample]

I'm using jQuery in my app, so I downloaded the jQuery version of 'rails.js' according to Part 3. I'm using the exception_logger gem, which requires the Prototype version of 'rails.js'. So I made 'rails.js' the Prototype version, and I created the file 'rails-jquery.js', which is the jQuery version.

I was using the exception_logger plugin, which is not Rails 3 compatible. There is an exception_logger gem which is almost Rails 3 compatible, but not quite, so I forked my own version.

I followed the instructions in Part 2 to define APP_CONFIG, but that didn't work for me. So I defined APP_CONFIG in its own initializer file. [sample]

With Rails 3, protect_from_forgery for delete buttons does not work without some work. I temporarily disabled protect_from_forgery for all delete actions.

I got an ActiveRecord::ReadOnlyRecord exception on update. To fix this, I pass :readonly => false to the related find. [reference]

The form_for method was failing for a scoped resource, so I switched to using a form_tag for that view.

Instead of using the dynamic_form plugin as specified in Part 3, I used the dynamic_form gem.

There was an issue related to time zones with some code that used Chronic. I had to build a UTC time manually to restore the application's behavior. [sample]

I followed the instructions in Part 2 to autoload the lib directory, but that didn't work for me, so I created an initializer file to load the lib directory. [sample]

Here are the final changes to my gem configuration.

Final Statement

My favorite feature of Rails 3? Bundler. I didn't realize how cool Bundler was until I understood the Bundler lock file. That eliminates a whole class of dependency problems that Rails projects were vulnerable to.