Close

Not a member yet? Register now and get started.

lock and key

Sign in to your account.

Account Login

Forgot your password?

Howto: Upgrade von Rails 2.3.10 auf Rails 3.0.4

10 Feb Posted by admin in Projekte, Ruby on Rails | Comments
Howto: Upgrade von Rails 2.3.10 auf Rails 3.0.4

Vor einiger Zeit wurde Rails3 vorgestellt und da viele Gems mittlerweile mit Rails3 besser funktionieren als mit Rails3 und teilweise die Rails2 Versionen nicht mehr weiterentwickelt werden habe ich mich beschlossen die ersten Projekte auf Rails3 umzustellen.

Um den Umstieg für mich selbst festzuhalten und meine Erfahrungen mit anderen zu teilen schreibe ich hier einmal nieder wie ich den Wechsel vollzogen habe.

Bundler macht das Leben leichter

Bei Rails2 werden die Gems in über die Datei config/enviroment.rb festgelegt. Hier kann es Probleme bei Updates von Gems geben, weil Rails2 die Abhängigkeiten von Gems nicht korrekt auflösen kann. Es kann also zum Beispiel passieren, dass ein Gem “activesupport” Version 2 voraussetzt, in den Abhängigkeiten steht aber nur “activesupport”. In diesem Fall würde Rails die aktuellste Version von “activesupport” installieren. Nämlich die Version 3, die aber nur mit Rails3 funktioniert.

Rails3 kann mit diesem Problem besser umgehen, da es auf Bundler setzt. Bundler ist ein gem welches Anhängigkeiten von Gems korrekt auflöst und die benötigten Gemversionen festsetzt.

Schritt 1: Integration von Bundler

Um den Umstieg zu erleichtern habe ich in mein Rails2 Projekt zunächst Bundler integriert.

Eine ausführliche Anleitung gibt es hier.

Da ich schrittweise vorgegangen bin und das Rails2 Projekt mit Bundler auch publizieren wollte musste ich Rails2 noch sagen, dass es Bundler nutzen soll diesen Schritt kann man sich aber wahrscheinlich sparen, wenn man direkt im Anschluss auf Rails3 umsteigt.

Schritt 2: Rails-XSS einbauen

Einer der wesentlichen Unterschie zwischen Rails2 und Rails3 ist die Integration vom “Rails-XSS” Gem in Rails3. Dieses Gem sorgt dafür, dass Ausgaben in Views automatisch escaped werden. Um den Umstieg zu erleichtern binde ich zunächst dieses Gem ein.
Installation:

Da ich bereits Bundler nutze ist die Installation von Rails xss ziemlich simpel
Folgende Zeile in die “Gemfile”

gem "erubis" // rails_xss ist davon abhängig
gem "rails_xss"

und danach einfach:

bundle install

Danach müssen die Views überarbeitet werden: man kann sich jeden “h”-Helper im View sparen und an Stellen an denen HTML-Code ausgegeben werden soll muss ein .html_safe eingebunden werden.

Vorher:

<%=link_to h(user.name), user%>
<%=link_to user.text_with_safe_html, user     // "<strong>ich bin nett</strong>"%>


Nachher

<%=link_to user.name, user%>
<%=link_to user.text_with_safe_html.html_safe, user     // "<strong>ich bin nett</strong>"%>

Schritt 3: RVM installieren

Da Rails2 und Rails3 unterschiedliche Ruby-Versionen voraussetzen und auf meinem Rechner sowohl Rails2 als auch Rails3 Projekte laufen sollen brauchte ich RVM. RVM bedeutet “Ruby Version Manager” und sorgt dafür, dass man beliebig viele verschiedene Ruby-Versionen installieren kann ohne das diese sich gegenseitig “stören”.

Zur Installation bin ich wie auf der RVM-Homepage beschrieben vorgegangen.

Schritt 4: Ruby 1.9.2 installieren

Für Rails3 installiere ich zunächst die passende Ruby-Version. Im Moment ist 1.9.2 die aktuellste Version.

Dazu wechsle ich einfach in der Konsole ins Projektverzeichnis und gebe

rvm install 1.9.2

ein und warte ein wenig. Die Installation kann einige Minuten dauern, klappte bei mir aber auf Anhieb.

Schritt 5: RVM und Gemsets konfigurieren

RVM unterstützt sogenannte Gemsets mit denen es möglich ist die Gems eines Projektes von denen anderer zu isolieren.

Um unserem Projekt zu sagen welches Gemset und welche Rubyversion es nutzen soll müssen wir dies noch entsprechen zu konfigurieren.

Das ganze ist ziemlich einfach:

 rvm use 1.9.2@projektname --rvmrc

Schritt 6: Upgrade auf Rails3 vorbereiten

Bei Rails3 hat sich einiges an der API geändert und ich habe natürlich wenig Lust alle Änderungen von Hand umzusetzen. Glücklicherweise gibt es das “rails_upgrade”-Plugin was bei der Umstellung behilflich sein soll.

Schrtt 6.1  rails_ugrade installieren

Ich installiere mir das Plugin mit:

script/plugin install git://github.com/rails/rails_upgrade.git

Schrtt 6.2  rails:upgrade:check

Und führe anschließend folgenden Befehl in der Konsole aus:

rake rails:upgrade:check

Dabei erhalte ich einige Hinweise und Warnungen:

Soon-to-be-deprecated ActiveRecord calls
Methods such as find(:all), find(:first), finds with conditions, and the :joins option will soon be deprecated.
More information: http://m.onkey.org/2010/1/22/active-record-query-interface

Naja, “soon” hat wohl noch Zeit, oder? ;)

named_scope is now just scope
The named_scope method has been renamed to just scope.
More information: http://github.com/rails/rails/commit/d60bb0a9e4be2ac0a9de9a69041a4ddc2e0cc914                                                           

The culprits:
        - /home/dennis/workspace/projekt/app/models/user.rb
        - /home/dennis/workspace/projekt/app/models/image.rb

Also ab in die beiden Dateien und named_scope durch scope ersetzen.

Old router API
The router API has totally changed.
More information: http://yehudakatz.com/2009/12/26/the-rails-3-router-rack-it-up/                                                                         

The culprits:
        - config/routes.rb

Uff, das klingt nach Arbeit. Aber dazu später mehr.

Deprecated test_help path
You now must require 'rails/test_help' not just 'test_help'.
More information: http://weblog.rubyonrails.org/2009/9/1/gem-packaging-best-practices                                                                     

The culprits:
        - /home/dennis/workspace/projekt/test/test_helper.rb
New file needed: config/application.rb
You need to add a config/application.rb.
More information: http://omgbloglol.com/post/353978923/the-path-to-rails-3-approaching-the-upgrade                                                        

The culprits:
        - config/application.rb

Gesagt, getan – Die Datei wurde erstellt. Auch wenn ich vermute, dass der spätere Installer das ohnehin machen müsste.

Deprecated constant(s)
Constants like RAILS_ENV, RAILS_ROOT, and RAILS_DEFAULT_LOGGER are now deprecated.
More information: http://litanyagainstfear.com/blog/2010/02/03/the-rails-module/

Hmm, das nervt mich doch sehr. Sowas habe ich in vielen Projekten benutzt.
Statt RAILS_ENV nutze ich dann halt jetzt Rails.env, RAILS_ROOT wird zu Rails.root usw.

Old Rails generator API
A plugin in the app is using the old generator API (a new one may be available at http://github.com/trydionel/rails3-generators).
More information: http://blog.plataformatec.com.br/2010/01/discovering-rails-3-generators/

Zwei der verbauten Plugins nutzen wohl noch alte Generatoren. Da ich bisher gar nicht wusste, dass diese überhaupt Generatoren haben ignoriere ich dies erstmal.
Ich denke die Plugins muss ich später eh ersetzen.

Deprecated session secret setting
Previously, session secret was set directly on ActionController::Base; it's now config.secret_token.
More information: http://lindsaar.net/2010/4/7/rails_3_session_secret_and_session_store                                                                   

The culprits:
        - /home/dennis/workspace/projekt/config/initializers/session_store.rb

Um dieses Problem zu lösen ersetze ich in der betroffenen Datei

ActionController::Base.session = {
  :key         => '_projekt_session',
  :secret      => '4683f0184adasdasffffffffasffffffasfasdasdasdasdasdasd10ff9cbf984393f2a12138689fb'
}

durch

Rails.application.config.session_store :cookie_store, :key => "_projekt_session"

Und lege unter config/initializers/cookie_verification_secret.rb eine Datei mit folgendem Inhalt an:

Rails.application.config.cookie_secret = '4683f0184adasdasffffffffasffffffasfasdasdasdasdasdasd10ff9cbf984393f2a12138689fb'

Nachdem ich alles ausgemerzt hatte habe ich nochmals zur Kontrolle

rake rails:upgrade:check

eingegeben und siehe da: bis auf die Sachen die ich ignorieren wollte alles verschwunden.

Schritt 6.3 rails:upgrade:backup

Als nächstes werden config Dateien von Rails, die gleich überschrieben werden gesichert. Dazu einfach folgendes im Terminal eingeben:

rake rails:upgrade:backup

Schrtt 6.4 rake rails:upgrade:routes

Um das Routing auf Rails3 anzupassen (siehe oben) führe ich folgendes in der Konsole aus:

rake rails:upgrade:routes

Schrtt 6.5 rails:upgrade:gems

Mit der Eingabe von
rake rails:upgrade:gems

teilte mir mit, dass ich bitte mein Gemfile durch  ‘gem “rails”, “3.0.0.beta3′  ersetzen solle. Diesen Schritt überspringe ich erstmal, da ich ja bereits bundler nutze und mein Gemfile noch benötige.

Schritt 7: Update von Rails 2 auf Rails 3

Jetzt wird es ernst – im nächsten Schritt wird die Rails Konfiguration auf Rails3 umgestellt:

rake rails:upgrade:configuration

Dieser Befehl parst die aktuelle Konfiguration und gibt die neue Rails3 Konfiguration aus. Diese muss dann in die config/application.rb eingefügt werden.

Um jetzt den Rails Code auf Rails3 umzustellen gehe ich wie folgt vor:

rails new . -J -d mysql

Damit erstelle ich im aktuellen Projekt ein neues Rails -Projekt auf Basis von Rails3. Der Parameter -J sorgt dafür, dass er mir kein Prototype mit installiert, da ich anschließend eh auf jquery umsteigen möchte.

Der Installer fragt bei jeder vorhandenen Datei nach ob er diese ersetzen darf.

Bevor ich die jeweiligen Dateien ersetze schaue ich mir die Originaldatei an und kopiere sie mir in ein anderen Dokument, lasse sie dann ersetzen und füge gegebenenfalls fehlende Konfigurationen wieder ein. Für mich traf das speziell für die Dateien “application_controller.rb”, “application_heler.rb”, “Gemfile”, “.gitignore” und die “database.yml” zu.

In der database.yml muss jetzt noch der Adapter auf “mysql2″ umgestellt werden.

Als nächsten Schritt stelle ich meine “Gemfile” Datei um:

Ich erhöhe die Rails-Version auf 3.0.4 und entferne bei einigen Gems die Versionsnummer damit die Abhängigkeiten von bundler korrekt aufegelöst werden.

mit “bundle update” installiere ich jetzt die passenden Gems und das Projekt ist auf Rails3 umgestellt.

Schritt 8: Try and error

Ich habe wirklich die leise Hoffnung, dass das Upgrade jetzt abgeschlossen ist und versuche mit “rails s” den Server zu starten. Natürlich klappt das nicht so, wie es sollte und ich erhalte folgende Fehlermeldung:

/home/dennis/workspace/projekt/config/application.rb:4:in `<module:Projekt>': uninitialized constant Rails::Application (NameError)
from /home/dennis/workspace/projekt/config/application.rb:3:in `<top (required)>'
from /home/dennis/.rvm/gems/ruby-1.9.2-p0@projekt/gems/railties-3.0.4/lib/rails/commands.rb:28:in `require'
from /home/dennis/.rvm/gems/ruby-1.9.2-p0@projekt/gems/railties-3.0.4/lib/rails/commands.rb:28:in `block in <top (required)>'
from /home/dennis/.rvm/gems/ruby-1.9.2-p0@projekt/gems/railties-3.0.4/lib/rails/commands.rb:27:in `tap'
from /home/dennis/.rvm/gems/ruby-1.9.2-p0@projekt/gems/railties-3.0.4/lib/rails/commands.rb:27:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'

Nach langer Fehlersuche und Deaktivierung verschiedener Gems stelle ich fest, dass man in der config/application.rb in Zeile 2

require 'rails/all'

einfügen muss.

Beim erneuten Start des Servers stellte sich raus, dass er nicht alle Gems lädt. Dazu habe ich noch folgende Zeile in die config/application.rb eingefügt:

Bundler.require(:default, Rails.env) if defined?(Bundler)

Als nächste Fehlermeldung erhielt ich

config/initializers/new_rails_defaults.rb:14:in `<top (required)>': undefined method `generate_best_match=' for ActionDispatch::Routing:Module (NoMethodError)

Die new_rails_default.rb sorgte bei Rails2 dafür, dass das Verhalten auf Rails3 angepasst wurde und kann natürlich entfernt werden.

Jetzt muss ich mich nur noch durch die Fehlermeldungen der gestarteten Application kämpfen, veraltete Plugins und Gems ersetzen und einige Generatoren neu ausführen.

und schon läufts!

 


Leave a comment