#282 Upgrading to Rails 3.1
Rails 3.1 est enfin sorti. On trouve un bon aperçu des nouvelles fonctionnalités dans les Release Notes sur le site RailsGuides. Certaines ont déjà été abordées sur Railscasts ainsi que sur Asciicasts. Dans cet épisode, nous allons nous concentrer sur la migration de Rails 3.0 à Rails 3.1 et nous utiliserons le site Railscasts pour la démonstration.
Préparer Le Site
Avant de passer le site sous Rails 3.1, nous allons avoir besoin d'effectuer quelques opérations de préparation. Si le site n'utilise pas encore la dernière version de Rails 3.0 (3.0.10
actuellement), nous allons devoir le mettre à jour. Nous pouvons le faire en changeant la version dans le Gemfile et en lançant bundle
.
gem "rails", "3.0.10"
Nous allons ensuite lancer la suite de tests de l'application afin de s'assurer qu'elle passe toujours et que nous n'avons pas d'erreur de dépreciation. Si nous en rencontrons, nous devons les corriger avant de continuer. Le code de Railscasts passe, nous pouvons donc passer à la migration.
Migration
Nous sommes maintenant prêts à migrer le site. Nous allons le faire dans un nouvelle branche Git que nous appellerons rails31
.
$ git checkout -b rails31
Migrer vers Rails 3.1 est plutôt simple. Nous avons juste besoin d'aller dans le Gemfile de notre application et de changer à nouveau la version de Rails pour mettre le numéro de la dernière (actuellement 3.1.0
).
gem "rails", "3.1.0"
Nous pouvons maintenant lancer bundle update
pour installer la nouvelle version. Le seul autre changement que nous devons opérer a lieu dans le fichier de configuration development.rb
. Nous devons supprimer ou commenter la ligne suivante.
# config.action_view.debug_rjs = true
Si nous lançons nos tests à nouveau, nous allons voir qu'ils passent toujours. Nous pouvons même démarrer le serveur Rails et tester dans notre navigateur.
Modifier notre application pour qu'elle utilise l'Asset Pipeline
L'asset pipeline est une des plus importantes fonctionnalités de Rails 3.1. Toutefois, les images, CSS et JavaScripts de notre application se situent toujours dans le dossier /public
de notre application, nous n'en tirons donc pas avantage. L'asset pipeline est totalement optionnel et n'est pas actif tant que nous ne le demandons pas. De cette manière, si nous ne sommes pas sûrs de vouloir l'utiliser, cela ne nous empêche pas de migrer vers Rails 3.1. Étant donné la facilité de migration, il y a très peu de raisons de ne pas sauter le pas.
Si nous voulons utiliser l'asset pipeline, nous devons l'activer. Pour ce faire, nous devons ajouter les lignes suivantes à notre Gemfile
(extraites du Gemfile
généré par Rails 3.1).
# Gems used only for assets and not required # in production environments by default. group :assets do gem 'sass-rails', " ~> 3.1.0" gem 'coffee-rails', " ~> 3.1.0" gem 'uglifier' end gem 'jquery-rails'
Ce code crée un groupe assets
et y place quelques gems relatives aux assets. On y trouve la gem jquery-rails
, nous pourrons donc utiliser jQuery (si vous préférez Prototype, vous pouvez utiliser la gem prototype-rails
gem). Nous allons également devoir modifier le fichier /config/application.rb
pour remplacer ce code :
# If you have a Gemfile, require the gems listed there, including any gems # you've limited to :test, :development, or :production. Bundler.require(:default, Rails.env) if defined?(Bundler)
par celui-ci :
if defined?(Bundler) # If you precompile assets before deploying to production, use this line Bundler.require *Rails.groups(:assets => %w(development test)) # If you want your assets lazily compiled in production, use this line # Bundler.require(:default, :assets, Rails.env) end
Ce code ajoute le groupe assets
aux groupes requis par Bundler
. Nous allons de plus devoir activer l'asset pipeline dans ce fichier. Cela se fait en ajoutant les lignes suivantes dans la classe Application
:
# Enable the asset pipeline config.assets.enabled = true # Version of your assets, change this if you want to expire all your assets config.assets.version = '1.0'
Ce code active l'asset pipeline et lui donne un numéro de version. Ce numéro peut être changé pour expirer les assets.
Il nous faut également changer la configuration de chaque environnement. Nous allons commencer par development.rb
. Nous avons deux changements à faire de façon à ce que les assets ne soient pas compressés et pour activer le debug des assets.
# Do not compress assets config.assets.compress = false # Expands the lines which load the assets config.assets.debug = true
Passons à production.rb
.
# Compress JavaScript and CSS config.assets.compress = true # Don't fallback to assets pipeline config.assets.compile = false # Generate digests for assets URLs config.assets.digest = true
En mode production, nous voulons voir les assets compressés mais nous mettons compile
à false
car nous ne voulons pas que l'asset pipeline soit appelé alors que nous allons précompiler les assets. Nous mettons digest
à true
de façon à ce que les URLs des assets aient une fingerprint. Bien sûr, nous pouvons configurer tout cela pour l'adapter aux besoins de notre application en production.
Enfin, nous allons modifier l'environnement de test. Ici nous précisons que les fichiers statiques doivent être servis et mis en cache. Nous activons également le debug des assets.
# Configure static asset server for tests with Cache-Control for performance config.serve_static_assets = true config.static_cache_control = "public, max-age=3600" # Allow pass debug_assets=true as a query parameter to load pages with unpackaged assets config.assets.allow_debugging = true
Si nous utilisons Git pour contrôler les sources de notre application, nous pouvons également modifier le fichier .gitignore
et ajouter le dossier .sass-cache
à la liste des éléments ignorés. Nous ne voulons pas le cache de SASS dans Git.
.sass-cache/
Déplacer les assets
Maintenant que notre asset pipeline est configuré, il est temps de créer un dossier /app/assets
. Nous pouvons ensuite déplacer les dossiers images
, javascripts
et stylesheets
de /public
vers /app/assets
.
$ mkdir app/assets $ mv public/images/ app/assets/ $ mv public/javascripts/ app/assets/ $ mv public/stylesheets/ app/assets/
Certains fichiers que nous avons déplacés ne sont plus nécessaires, ceux liés à jQuery dans le dossier javascripts
par exemple. Ils sont inclus dans la gem jQuery, nous pouvons donc supprimer les fichiers jquery.js
, jquery.min.js
et rails.js
. Il est maintenant temps de décider de si nous devons placer certains fichiers, comme les plugins jQuery, dans /lib/assets
ou /vendor/assets
, tel que vu dans l'épisode 279 [regarder, lire].
Nous devons ensuite créer les fichiers de manifest. Cette application contient déjà les fichiers application.js
et application.css
, nous n'avons donc pas besoin de les créer. Nous allons commencer par le fichier CSS. Pour le transformer en manifest, nous devons ajouter, au début de celui-ci, quelques commentaires qui indiqueront à Sprockets quels fichiers inclure (la syntaxe de Sprockets est également vue dans l'épisode 279). Nous allons dire à Sprockets d'inclure le reste du fichier ainsi que tout ceux présents dans le dossier stylesheets
et ses sous dossiers.
/* *= require_self *= require_tree . */ /* rest of file omitted */
Nous pouvons faire la même chose pour le fichier application.js
mais ce sera légèrement différent car nous voulons inclure jQuery.
//= require jquery //= require jquery_ujs //= require_self //= require_tree . /* rest of file omitted */
Pour rappel, nous ajoutons require_self
ici car le reste du fichier contient du code et require_tree
pour inclure les fichiers contenus dans le même dossier.
Nous allons devoir aller dans le layout de l'application pour changer les lignes d'inclusion des fichiers CSS et JavaScript afin qu'elles référencent uniquement les fichiers nécessaires, puisque les autres fichiers sont inclus via les manifests.
<%= stylesheet_link_tag "application" %> <%= javascript_include_tag "application", "http://cdn.sublimevideo.net/js/3s7oes9q.js" %>
Les fichiers JavaScript nécessaires à l'application comprennent un fichier externe qui ne sera pas inclus par l'asset pipeline. Pour celui-ci, nous avons toujours besoin d'une inclusion explicite comme ci-dessus.
Il est maintenant temps de tester notre application dans le navigateur pour nous assurer que toutes nos modifications ont fonctionné. Avant cela, nous allons lancer une nouvelle fois bundle
pour installer les gems que nous avons ajoutées. Cela fait, nous pouvons lancer le serveur.
$ rails s
En dehors de quelques images cassées (le logo en haut de l'écran par exemple), tout semble fonctionner.
Le problème est que les URLs des images ont été hard-codée dans le fichier de layout.
<img src="/images/railscasts_logo.png" width="423" height="56" alt="RailsCasts = Ruby on Rails Screencasts"/>
Cela ne peut pas fonctionner puisque les images de notre application ne sont plus dans le dossier /public/images
. La solution la plus simple pourrait être de changer l'url de l'image de /images/railscasts_logo.png
à /assets/railscasts_logo.png
mais bien que cela marche en développement, ce ne sera pas le cas en production. Si l'option assets.digest
est activée, un hash sera ajouté au nom de fichier, la référence statique vers celui-ci ne fonctionnera plus. Nous devons donc toujours utiliser le helper. Celui-ci va lier l'image correctement en développement comment en production.
<%= image_tag("railscasts_logo.png", :size => "423x56", :alt => "RailsCasts - Ruby on Rails Screencasts") %>
Nous allons devoir chercher, dans notre application, toues les références statiques et faire en sorte qu'elles utilisent le helper, comme ci-dessus. Si nous rechargeons la page, l'image apparait, nous indiquant que notre asset pipeline fonctionne correctement.
Nous avons terminé notre migration vers Rails 3.1. Il y a d'autres fonctionnalités dont vous pouvez tirer avantage. Cela vaut la peine de jeter un œil sur les autres épisodes autour de Rails 3.1 pour voir ce qui pourra vous être utile.