Zum Inhalt

Rails aktualisieren

Anfangs Januar 2013 gab es 2 kritische Sicherheitslücken die ein sofortiges Update auf die aktuellste Version von Rails verlangten. Wie aber geht man so etwas an und wie wird man überhaupt über eine neue Version informiert? Dier Eintrag liefert Antworten zu diesen und weiteren Fragen rund um die Aktualisierung einer Rails Anwendung.

Neue Version?

Informationen über neue Versionen findet man auf der offiziellen Webseite RubyOnRails.org. Wem es zu Aufwendig ist diese Seite regelmässig aufzurufen kann auch @Rails auf Twitter folgen oder Podcasts wie Ruby 5 hören. Durch die grosse Verbreitung informieren auch Newsportale wie Heise.de oder Golem.de jeweils sehr zeitnah über neue Versionen oder Probleme mit Rails.

Zu aktualisierende Pakete finden

Das Tool Bundler hilft einem nicht nur bei der Paketverwaltung und dem auflösen von Abhängigkeiten, sondern es bietet auch eine Möglichkeit um veraltete Pakete zu finden. Dazu wechselt man ins Verzeichnis seiner Rails-Anwendung und führt diesen Befehl aus:

bundle outdated
Fetching gem metadata from https://rubygems.org/...........
Fetching gem metadata from https://rubygems.org/..

Outdated gems included in the bundle:
  * activesupport (3.2.11 > 3.2.8)
  * builder (3.1.4 > 3.0.4)
  * activemodel (3.2.11 > 3.2.8)
  * sprockets (2.8.2 > 2.1.3)
  * actionpack (3.2.11 > 3.2.8)
  * mail (2.5.3 > 2.4.4)
  * actionmailer (3.2.11 > 3.2.8)
  * activerecord (3.2.11 > 3.2.8)
  * activeresource (3.2.11 > 3.2.8)
  * railties (3.2.11 > 3.2.8)
  * rails (3.2.11 > 3.2.8)

Pakete aktualisieren

Sollte Bundler nur wenige Gems melden genügt es diese einzeln zu aktualisieren. Dazu ersetzt man [name] durch den entsprechende Paketnamen:

sudo gem update [name]

Alternativ kann man auch gleich alle auf dem System installierten Gems aktualisieren. Dazu genügt es beim Befehlsaufruf keinen Paketnamen zu nennen:

sudo gem update

Neue Versionen von Gems können inkompatible Änderungen enthalten. Wenn der Autor eines Gems einen entsprechenden Hinweis hinterlegt kann die Ausgabe des oberen Befehls so aussehen:

...
Fetching: paperclip-3.4.0.gem (100%)
##################################################
#  NOTE FOR UPGRADING FROM PRE-3.0 VERSION       #
##################################################

Paperclip 3.0 introduces a non-backward compatible change in your attachment
path. This will help to prevent attachment name clashes when you have
multiple attachments with the same name. If you didn't alter your
attachment's path and are using Paperclip's default, you'll have to add
`:path` and `:url` to your `has_attached_file` definition. For example:

    has_attached_file :avatar,
      :path => ":rails_root/public/system/:attachment/:id/:style/:filename",
      :url => "/system/:attachment/:id/:style/:filename"

Successfully installed cocaine-0.4.2
Successfully installed paperclip-3.4.0
...

Hier wird von Paperclip auf ein neues Verhalten beim Ablageort von Anhängen hingewiesen. Diese Informationen helfen einem abzuschätzen ob man die neue Version gleich verwenden will oder ob grössere Umbauten nötig sind.

Wird so ein Hinweis nicht hinterlegt bleibt einem nur das (automatisierte) testen der Anwendung nach dem Update um allfällige Probleme zu finden.

Rails aktualisieren

Nachdem die Pakete aktualisiert sind öffnet man das Gemfile und sucht die von Bundler als veraltet markierten Gems:

source 'https://rubygems.org'

gem 'rails', '3.2.8'

# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'

gem 'sqlite3'

# Gems used only for assets and not required
# in production environments by default.
group :assets do
  gem 'sass-rails',   '~> 3.2.3'
  gem 'coffee-rails', '~> 3.2.1'

  # See https://github.com/sstephenson/execjs#readme for more supported runtimes
  gem 'therubyracer', :platforms => :ruby

  gem 'uglifier', '>= 1.0.3'
end

gem 'jquery-rails'

Um die neue Version von Rails zu nutzen ersetzt man die Version 3.2.8 durch 3.2.11:

gem 'rails', '3.2.11'

Nach dem gleichen Muster geht man bei den anderen Gems vor. Ist man damit durch empfiehlt sich nochmals mit Bundler die Pakete zu aktualisieren und nach veralteten Paketen zu suchen:

bundle update
 bundle outdated
Fetching gem metadata from https://rubygems.org/...........
Fetching gem metadata from https://rubygems.org/..

Outdated gems included in the bundle:
  * builder (3.1.4 > 3.0.4)
  * sprockets (2.8.2 > 2.2.2)
  * mail (2.5.3 > 2.4.4)

Da diese Gems nicht im Gemfile aufgeführt sind handelt es sich um Abhängigkeiten anderer Pakete. Im Gemfile.lock kann man nachschauen welche Pakete nach dieser Version verlangen. So lange diese Pakete nicht auf die neue Version wechseln müssen die älteren Versionen auf dem System bleiben (und werden von Bundler entsprechend angezeigt).

Allfällige Konfigurationsänderungen an Rails werden über den Rake-Task rails:update durchgeführt. Dies ist vor allem bei grösseren Versionswechseln (wie 3.1 auf 3.2) nötig. Es schadet aber nicht diesen Task bei jeder Aktualisierung auszuführen:

rake rails:update

Sollte es dabei zu Problemen kommen kann man mittels der Eingabe von h die Hilfe aufrufen und mit d einen Diff der Änderungen anzeigen.

Fazit

Ein Update von Rails lässt sich bei kleineren Versionswechseln recht schnell und ohne grosse Probleme durchführen. Ob noch alles wie gewünscht funktioniert kann aber nur ein eingehender Test zeigen. Eine automatisierte Testsuite kann einem auch in diesem Fall viel Arbeit abnehmen.