Rails 3 is now beta and the core team is asking people to try it out and report issues back. We decided to do a small spike to get some experience with the upgrade process and see if we could help identify any problems. The application we worked on was our own Pivotal Pulse CI aggregation display (which you can see in action).
Here’s a quick overview of the steps we went through:
- Install Ruby 1.8.7 using RVM
- Install Rails beta gems
- Upgrade the app using the rails_upgrade plugin
- Tweak things a lot
- Drop incompatible dependencies
The first thing we had to do was install RVM. Our development machines are standardized on Ruby 1.8.6 — which we wanted to keep, of course — but Rails 3 requires Ruby 1.8.7. We installed patchlevel 174 after finding that higher patchlevels are not stable with RVM.
$ rvm install 1.8.7-p174
We also found it useful to set 1.8.7 as the default.
$ rvm use 1.8.7-p174 --default
That will also set the ruby that TextMate uses (but not RubyMine). If you don’t want to set 1.8.7 as the default, you can manually set the version of Ruby that TextMate uses by specifying the TM_RUBY shell variable. (Tips on how to manage Ruby VM preference in RubyMine appreciated.)
With Ruby 1.8.7 set up, it’s time to install Rails. You need to install from gems, but because it’s a pre-release gem, there are a few extra steps. Here’s what it took on our side:
$ gem install tzinfo builder memcache-client rack rack-test rack-mount erubis mail text-format thor bundler i18n
$ gem install rails --pre
$ gem install railties --pre
$ gem install rack-mount -v 0.4.7
The first line installs the Rails 3 dependencies that are not, themselves, pre-release gems. RubyGems 1.3.5 has a bug that it won’t install non-pre-release gem dependencies of a pre-release gem. This is fixed in 1.3.6, we hear, but that release has other problems. The second line installs the Rails 3 pre-release gem. The third line fixes a “can’t find executable rails” error, and the fourth line installs the right verison of rack-mount — the current version, 0.5.1, seems to break things.
At this point, you should test your installation by generating and running a new app.
$ rails fiddle
$ cd fiddle
$ rails server # => replaces ruby script/server
But what we’re really interested in is an upgrade. Step 1 is the rails_upgrade plugin. The Pulse app was managing gems using geminstaller instead of Rails config.gem feature, so we added our gems to the bundler Gemfile by hand instead of using the upgrader task.
An interesting change in Rails 3 is that
config/environment.rb has faded into obscurity. Init code that was located within the initialize block should be moved into
config/application.rb. Any other code should be moved into initializer files in the
config/initializers/ directory. Be careful with scoping of globals; you may need to add some
::s to the front of your constants to get them to work right.
The app needed a few other minor tweaks to get running:
- route conversion in the rails_upgrade plugin didn’t retain all the options on the singleton resource definitions.
map.resource :login, :controller => "sessions" converted automatically to just
rails server failed because there was no
tmp/pids directory; once we created it, it started right up.
- output is now escaped by default in views, so in one place we needed to add
raw to get the output markup interpreted.
<%= historical_status_list(project) %> # =>
<%= raw historical_status_list(project) %>
We had a few dependencies that flat-out didn’t work; the most important of these were rspec and rspec-rails. The Pulse tests are all rspec, and while we were able to get them to run by installing Mutwin Kraus’ modified version of rspec-rails as a plugin, they didn’t come anywhere close to passing. This may be due to our use of foxy fixtures – calls such as
projects(:project_name) failed, as did references to fixture names in the foreign key fields in fixture yaml files.
Also not working:
Once we finished all the tweaks, we ran
rails server, and the application loaded and behaved normally (just not on the first attempt, heh). Pulse is a small enough project that we can say with at least some confidence that the app still works, even though the tests are red. It does feel a little dirty to check that code in though — even to a branch.