Upgrade der ObjectTime von Rails 2.3.4 zu Rails 3.2.1,
sowie JRuby 1.4.0 zu JRuby 1.6.7

Nachdem Rails in der Version 3.2 erschienen ist, haben wir uns dazu entschlossen, auch unsere mit JRuby on Rails erstellte Zeiterfassung auf den neusten technischen Stand zu bringen. Denn nur durch regelmäßige Updates aller relevanten Bibliotheken kann man dauerhaft sicherstellen, dass Rails-Anwendungen zuverlässig funktionieren und technisch auf dem neuesten Stand sind.

Und da sich gerade beim Schritt von Rails 2 zu Rails 3 im Rails-Framework einiges unter der Haube verändert hat (Neuerungen im Rails 3), z.B.

dokumentieren wir hier kurz die beim Upgrade von uns vollzogenen Schritte sowie relevante Stolperfallen.

Aktualisierung von JRuby

Erster Schritt war die Aktualisierung von JRuby, einfach die neue Version 1.6.7 auf jruby.org herunterladen und mit dem beiden Gems jruby-openssl und bundler installieren. Easy!

Aktualisierung von Rails

Danach erfolgt die Aktualisierung von Rails in drei Schritten.
(Hinweis: Es kann nicht schaden, vorher einen Tag in der Versionskontrolle zu setzen!)


1. Von Rails 2.3.4 zu Rails 3.0
Hier kann man sich gut an die 3 Railscasts #255 halten: Teil 1, Teil 2, Teil3
Kurz zusammengefasst: Mittels des Plugins rails_upgrade überprüft man was angepasst wird und kann sich ein Backup von anzupassenden Dateien erstellen lassen.
Nachdem im Projektverzeichnis ein Gemfile mit gem 'rails', '3.0.0' vorhanden ist, kann man mit Hilfe von bundle install Rails 3 in die Anwendung bringen.
Um jetzt den Quellcode auf Rails3 umzustellen führt man folgenden Befehl aus: rails new . -J -d mysql. Damit erstellt man im aktuellen Projekt ein neues Rails-Projekt auf Basis von Rails 3. Der Parameter -J sorgt dafür, dass kein Prototype installiert wird, da wir anschließend in unserem Projekt auf jQuery umsteigen möchten. Der Installer fragt bei jeder vorhandenen Datei nach ob er diese ersetzen darf. Man kann sich also spätestens auch jetzt noch bei Bedarf eine Sicherung der Datei anlegen.

Jetzt beginnt der Spaß. Viele der in Rails 2 benutzen Plugins und Gems funktionieren nicht unter Rails 3 und müssen daher ebenfalls aktualisiert werden. Hier muss man je nach Projekt individuell sehen, ob es eine neue Version gibt oder ob man doch etwas mehr Aufwand zum Umschreiben seines Codes aufwenden muss.
(Hinweis: In Rails 4 werden Plugins nicht mehr unterstützt. Daher ist es jetzt schon ratsam auf Gems umzusteigen.)

Außerdem wollen wir ja nun jQuery anstatt Prototyp als Javascript Bibliothek nutzen. Dafür muss man das Gem jquery-rails im Gemfile eintragen, um jQuery automatisch mit Rails 3 nutzen zu können. Durch die Änderung der Javascript Bibliothek stehen natürlich die Prototyp-Helper in den .rjs Templates nicht mehr zur Verfügung. Mit JQuery schreibt man dann eher

$('#foo').html("<%= escape_javascript(render "bar") %>"); 	
in z.B. .js.erb Templates.

Damit die Rails Anwendung auch mit JRuby läuft muss man im Gemfile noch folgende Gems eintragen

# Auszug
source 'http://rubygems.org'

gem 'rails', '3.0.0'

gem 'jruby-openssl',                  '= 0.7.5'
gem 'activerecord-jdbcmysql-adapter', '= 1.2.2'
... 	
Rails 3 kommt natürlich mit einer neueren I18n Version. Seit der Version 0.4.0 ist die Syntax der Interpolationen geändert worden. Aus {{}} wird %{}.


2. Von Rails 3.0 zu Rails 3.1
Neu in Rails 3.1 ist die Asset Pipeline - ein Framework um CSS- und Javascript-Dateien verkleinert, komprimiert und zusammengefügt auszuliefern. Außerdem kann man in den Assets CoffeScript, Sass oder Erb nutzen.

Da es hierzu schon unzählige Tutorials, wird für das Upgrade nur auf einige verweisen:

Bei der Asset-Pipeline sind wir dann auf ein Problem gestoßen. Unsere App läuft unter einem context_path z.b. /demo. Wenn man in ein style.css.scss.erb auf ein Bild als background-image zugreifen will, soll man nun folgendes schreiben:

.css-class {
  background-image: url('<%= asset_path 'bg.png' %>');
 }	
Das liefert nun aber nicht wie erwartet /demo/assets/bg.png sondern /assets/bg.png! Es scheint ein Problem bei der Erstellung der Rails Assets mittels rake assets::precompile zu sein.
Die Lösung wird hier beschrieben. Bei rake assets::precompile einfach den context_path mittels RAILS_RELATIVE_URL_ROOT=/demo mitgeben.


3. Von Rails 3.1 zu Rails 3.2
Die Umstellung auf Rails 3.2 ist nun schnell erledigt. Lediglich im Gemfile, in der development.rb und test.rb sind kleine Anpassungen zu machen. Welche Neuerungen in der Version enthalten sind, findet man auch in diesem Railscast - Upgrading to Rails 3.2.


Fazit

Das JRuby-Upgrade gestaltete sich sehr erfreulicherweise sehr einfach und auch das Zusammenspiel der neuen JRuby-Version mit Rails 3.2.1 klappt hervorragend. Man sollte nur versuchen seine Anwendungen in kürzeren Zyklen zu aktualisieren, um sie so nah wie möglich auf den neusten Technischen Stand zu halten.
Stichwort: Continuous Upgrades!