mardi, mars 18, 2008

Migration "Pas à pas" d'une application ruby on rails de 1.2.6 vers 2.0.2 (part 2)

Dans le post précédent nous avons vu comment migrer de 1.2.2 vers 1.2.6
Maintenant nous allons passer de 1.2.6 à 2.0.2


Je ne l'ai pas dit dans mon post précédent tellement ça me paraissait évident, mais utiliser systématiquement subversion (ou un autre système: cvs, git...) pour pouvoir revenir en arrière. C'est indispensable !!


> rake rails:unfreeze

> svn delete vendor/rails

> gem list rails

*** LOCAL GEMS ***

rails (1.2.6)

> gem update rails
Successfully installed rails-2.0.2
1 gem installed
Gems updated: rails

> gem list rails

*** LOCAL GEMS ***

rails (2.0.2, 1.2.6)

> edit config/environment.rb

Changer
RAILS_GEM_VERSION = '1.2.6' unless defined? RAILS_GEM_VERSION
En:
RAILS_GEM_VERSION = '2.0.2' unless defined? RAILS_GEM_VERSION

>ruby script\about

      *******************************************************************
      * config.breakpoint_server has been deprecated and has no effect. *
      *******************************************************************

About your application's environment
Ruby version              1.8.6 (i386-mswin32)
RubyGems version          1.0.1
Rails version             2.0.2
Active Record version     2.0.2
Action Pack version       2.0.2
Active Resource version   2.0.2
Action Mailer version     2.0.2
Active Support version    2.0.2
Application root          C:/developement/ruby/appli
Environment               development
Database adapter          mysql
Database schema version   8

Si vous avez le même warning que moi, éditer le fichier development.rb et enlevé les lignes suivantes:

# Enable the breakpoint server that script/breakpointer connects to
config.breakpoint_server = true
puis installer ruby-debug comme expliqué ici: Fixing-config-breakpoint-server

> rake rails:update

modifie 
  config/boot.rb

  public/javascripts/control.js
  public/javascripts/dragdrop.js
  public/javascripts/effects.js
  public/javascripts/prototype.js

> rake log:clear tmp:clear db:test:purge

Editer database.yml J'aime bien ajouter l'encoding pour MySql:

development:
  adapter: mysql
  *encoding: utf8* (sans les étoiles autour ;) )
  database: appli_development
  username: appli
  password: appli
  host: localhost

> rake db:reset
(optionnel ?)

> rake db:migrate:reset
...

m à j de db/schema.rb

> rake test
...
36 tests, 95 assertions, 0 failures, 0 errors
...
33 tests, 63 assertions, 0 failures, 0 errors

> ruby script/server
=> Booting Mongrel (use 'script/server webrick' to force WEBrick)
=> Rails application starting on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
** Starting Mongrel listening at 0.0.0.0:3000
** Starting Rails with development environment...
** Rails loaded.
** Loading any Rails specific GemPlugins
** Signals ready.  INT => stop (no restart).
** Mongrel 1.1.4 available at 0.0.0.0:3000
** Use CTRL-C to stop.
/!\ FAILSAFE /!\  Tue Mar 18 10:16:56 +0100 2008
  Status: 500 Internal Server Error
  A secret is required to generate an integrity hash for cookie session data. Use config.action_controller.session = { :session_key => 

"_mya
pp_session", :secret => "some secret phrase of at least 30 characters" } in config/environment.rb
    c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/session/cookie_store.rb:91:in `ensure_secret_secure'
    c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/session/cookie_store.rb:60:in `initialize'
...

http://localhost:3000/ retourne une erreur 500
Le plus simple que j'ai trouvé c'est de créer une nouvelle appli rails à côté:
> rails dummy

Remplacer le contenu de appli/config/environment.rb par celui de dummy (en garder une copie qq part)

> rake secret
Remplacer la ligne suivante:

  config.action_controller.session = {
    :session_key => '_dummy_session',
    :secret      => '1234abcde'
  }

par
  config.action_controller.session = {
    :session_key => '_appli_session',
    :secret      => 'secret generé par la commande rake secret'
  }

Ajouter toutes les conf specifiques à votre appli.
Par exemple dans mon cas j'avais ActionMailer, donc j'ai ajouté à la fin:
ActionMailer::Base.smtp_settings = {
  :address  => 'smtp.truc.com',
  :port  => '25',
  :domain => 'www.truc.com'
}

Continuons la migration...
> rake test
...
> svn commit -m "updating to rails 2.0.2"

> rake rails:freeze:gems
...

> svn add vendor/rails

> rake deprecated
...

> ruby script/plugin remove deprecated
...
inutile maintenant

> svn commit -m "freezing rails 2.0.2"

> gem uninstall rails --version 1.2.6

A partir de là vous avez fait l'essentiel!!
Vous pouvez rentrer chez vous après une dure journée de labeur... ou bien fignoler le travail

Créer un fichier migrate_views.rb à la racine de l'appli: Ajouter:

Dir.glob('app/views/**/*.rhtml').each do |file|
  puts `svn mv #{file} #{file.gsub(/\.rhtml$/, '.html.erb')}`
end

> ruby migrate_views.rb
A         app\views\layouts\application.html.erb
D         app\views\layouts\application.rhtml
...

> rake test
...

> ruby script/server
...
Tester l'appli

Ajouter à production.rb

config.action_view.cache_template_loading            = true

Ajouter à test.rb
# Disable request forgery protection in test environment
config.action_controller.allow_forgery_protection    = false
Concernant routes.rb, je n'ai pas de solution miracle :(
Créer un une appli rails dummy à coté et utiliser un outil de conmparaison de fichier pour voir les différences et mettre votre routes.rb à jour.

Par exemple si vous n'utiliser pas le wsdl comme moi vous pouvez supprimer la ligne:
map.connect ':controller/service.wsdl', :action => 'wsdl'

On peut aussi copier/coller le README à la racine de l'appli dummy vers son appli rails

Dans test_helper.rb, on peut ajouter:

  # The only drawback to using transactional fixtures is when you actually 
  # need to test transactions.  Since your test is bracketed by a transaction,
  # any transactions started in your code will be automatically rolled back.
juste avant
self.use_transactional_fixtures = true
et
  # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
  #
  # Note: You'll currently still have to declare fixtures explicitly in integration tests
  # -- they do not yet inherit this setting
  fixtures :all

Si vous avez un script/breakpointer je pense que vous pouvez le supprimer...

Vous pouvez aussi changer tous vos fichiers dans db/migrate pour utiliser la nouvelle syntaxe des migrations (optionnel)

Il y a plein d'autre améliorations possibles dans les controller, dans les fixtures etc... cf: rails-2-0-it-s-done

Et Voilà ! Votre appli est migrée en Rails 2.0.2! Félicitations ;)

Technorati tags:

4 commentaires:

Benjamin Francisoud a dit…

Update:
- il existe d'autre extension à changer .rjs en .js.rjs, cf http://thelucid.com/articles/2007/05/16/rails-edge-getting-your-view-extensions-ready-for-edge
- on peut aussi supprimer le répertoire 'components' qui est deconseillé

Benjamin Francisoud a dit…

Update n°2:
Si vous utilisez le plugin 'restful_authentication', il faut changer redirect_to_url en redirect_to cf: http://www.slashdotdash.net/articles/2007/12/03/rails-2-upgrade-notes

Benjamin Francisoud a dit…

Update n°3:
Ajouter un répertoire config/initializers avec 2 fichiers:
inflections.rb et mime_types.rb récupéré d'une application rails 2.0 dummy

Offshore Software Development Company a dit…

I was exploring for ruby on rails development and alighted up on your send and i ought declare thanks for dividing such practical information.