Friday, October 2, 2009

Running a Ruby on Rails Application on OSX with Ruby 1.9

General

OSX comes preinstalled with ruby 1.87, however, ruby 1.9 has out there for quite a while now and does offer improvements in many areas, including performance, which is always a good trigger for an upgrade. A deeper overview can be found here.

Ruby 1.9

You can use MacPorts, Fink or compile from source. Hivelogic has a good post on how to install ruby on OSX here. I have chosen to use MacPorts as I use it for other ports:

$ sudo port install ruby1.9

If you are doing a side by side installation (i.e keeping you original ruby installation in place), you may want to do some symbolic linking to make sure the ruby, irb, gems, rake, ri and rdoc are pointing the 1.9 version. If you choose to skip this step, remember to use the ruby1.9, irb1.9, etc command instead.

Disclaimer: Please be careful with the below, the order and locations matter and one installation (yours) can be different than other (mine), if you are not familiar with OSX, bash and symbolic linking I suggest you do some readying before continuing with this step or just stick to using the 1.9 command namespace (See above).

The example below assume you ruby 1.9 is installed at /opt/local/bin/ruby1.9 (MacPort default location) and that your original ruby installation was a /System/Library/Frameworks/Ruby.framework/Versions/1.8 (OSX default location).

$ cd /System/Library/Frameworks/Ruby.framework/Versions
$ mkdir 1.9.1
$ mkdir 1.9.1/usr
$ mkdir 1.9.1/usr/bin

$ cd 1.9.1/usr/bin
$ ln -s /opt/local/bin/ruby1.9 ruby
$ ln -s /opt/local/bin/rake1.9 rake
$ ln -s /opt/local/bin/gem1.9 gem
$ ln -s /opt/local/bin/irb1.9 irb
$ ln -s /opt/local/bin/erb1.9 erb
$ ln -s /opt/local/bin/ri1.9 ri
$ ln -s /opt/local/bin/rdoc1.9 rdoc
$ ln -s /opt/local/bin/testrb1.9 testrb

$ cd /System/Library/Frameworks/Ruby.framework/Versions
$ rm Current
$ ln -s 1.9.1 Current

$ cd /usr/bin
#for some reason apple is linking directly to the v. 1.8 folder instead of the current directory, we will "fix" that.
$ mv gem gem1.8
$ ln -s /System/Library/Frameworks/Ruby.framework/Versions/Current/usr/bin/gem
#for some reason apple has put the rake executable in /usr/bin instead of in the current; directory, we will "fix" that.
$ mv rake rake1.8
$ ln -s /System/Library/Frameworks/Ruby.framework/Versions/Current/usr/bin/rake

To confirm you are running the correct ruby version:
$ ruby -v
$ gem env
$ irb
>> RUBY_VERSION

Rails

As you are installing a new ruby, you also need to reinstall all of you gems, as this artical is focused on ruby on rails, we will start with the rails gem. There is nothing exciting here, simply run the standard rails installation command

$ gem update --system
$ gem install rails

Other Gems

For the purposes of my application, I have installed the follwing gems:
actionmailer (2.3.4, 2.3.3)
actionpack (2.3.4, 2.3.3)
activerecord (2.3.4, 2.3.3)
activeresource (2.3.4, 2.3.3)
activesupport (2.3.4, 2.3.3)
builder (2.1.2)
cgi_multipart_eof_fix (2.5.0)
daemons (1.0.10)
fast_xs (0.7.3)
fastthread (1.0.7)
gem_plugin (0.2.3)
httpclient (2.1.5.2)
libxml-ruby (1.1.3)
macaddr (1.0.0)
mongrel (1.1.6)
mongrel_cluster (1.0.5)
mysql (2.8.1)
rack (1.0.0)
rails (2.3.4, 2.3.3)
rake (0.8.7)
rubygems-update (1.3.5)
rubyzip (0.9.1)
soap4r (1.5.8)
uuid (2.0.2)

Hacks

This is where the fun begins, some of the gems and rails modules are not fully baked for ruby 1.9, below are a list of hacks that I had to plug in to make my rails app work. Naturally, your case may be different, a good reference to gems under 1.9 can be found here.

mongrel gem
The 1.1.5 mongrel gem does not install over ruby 1.9. You may choose to fix it manually or install 1.1.6 from gems.rubyinstaller.org:

$ gem install mongrel --source http://gems.rubyinstaller.org

More info on this can be found here.

mongrel cluster
Needs a small syntax patch, fix the case statement at the end of the mongrel_cluster_ctl by replacing ":" with "then".

restful_authentication plugin
If you are using restful_authentication plugin you are likely to crash as soon as the plugin attempts to read data from cookies. This is due to a bug in active_support module. There is a documented patch here.

uploading
Most applications use some sort of uploading, mine does too. Rack 1.0.0 on 1.9 crashes does to unicode issues. There is a documented patch here.

ftools
ftools has been deprecated in 1.9, if your code is dependent on it, move to fileutils.

rubyzip gem
Uses ftools, you will need to remove the dependency. There is a documented patch here.

libxml-ruby gem
I found this gem to be unstable on 1.9, throwing many memory allocation errors. The solution was to update the libxml libs and then install the gem against the updated sources:

$ port install libxml2
$ gem install libxml-ruby -- --with-xml2-include=/opt/local/include/libxml2

More info on this can be found here.

soap4r
Broken, I monkey patched locally which was enough for my usage, but not a compelte solution. More info here.

These steps got my app on its feet, however, I am still testing stability and performance under the new setup. I will update this post if and when new problems or solutions come up.

3 comments:

  1. rack 1.0.1 includes a fix to the rack 1.0.0 issue mentioned above

    ReplyDelete
  2. other than soap4r, all other gems have been fixed by vendor

    ReplyDelete
  3. Not using RVM? It's a dream on Mac.

    ReplyDelete