Tutoriel Ruby on Rails

Apprendre Rails par l'exemple

Michael Hartl

Contenu

  1. Chapitre 1 De zéro au déploiement
    1. 1.1 Introduction
      1. 1.1.1 Commentaires pour les lecteurs différents
      2. 1.1.2 “Dimensionner” Rails
      3. 1.1.3 Conventions utilisées dans ce livre
    2. 1.2 Debout et au boulot
      1. 1.2.1 Environnements de développement
        1. IDEs
        2. Éditeurs de texte et lignes de commande
        3. Navigateurs
        4. Note à propos des outils
      2. 1.2.2 Ruby, RubyGems, Rails, et Git
        1. Installation de Rails (Windows)
        2. Installer Git
        3. Installer Ruby
        4. Installer RubyGems
        5. Installer Rails
      3. 1.2.3 La première application
      4. 1.2.4 Bundler
      5. 1.2.5 Le serveur rails (rails server)
      6. 1.2.6 Modèles-Vue-Contrôleur (MVC)
    3. 1.3 Contrôle de versions avec Git
      1. 1.3.1 Installation et réglages
        1. Initialisation des réglages système
        2. Initialisation des réglages du dépôt (repository)
      2. 1.3.2 Ajout et mandat de dépôt
      3. 1.3.3 Qu'est-ce que Git peut faire de bien pour vous ?
      4. 1.3.4 GitHub
      5. 1.3.5 Branch, edit, commit, merge
        1. Branch
        2. Edit
        3. Commit
        4. Merge
        5. Push
    4. 1.4 Déploiement
      1. 1.4.1 Réglages Heroku
      2. 1.4.2 Déploiement Heroku, première étape
      3. 1.4.3 Déploiement Heroku, seconde étape
      4. 1.4.4 Commandes Heroku
    5. 1.5 Conclusion
  2. Chapitre 2 Une application démo
    1. 2.1 Planifier l'application
      1. 2.1.1 Modéliser les utilisateurs
      2. 2.1.2 Modéliser les micro-messages
    2. 2.2 La ressource Utilisateurs (Users)
      1. 2.2.1 Un tour de l'utilisateur
      2. 2.2.2 MVC en action
      3. 2.2.3 Faiblesses de la ressource Utilisateurs (Users)
    3. 2.3 La ressource Micro-messages (Microposts)
      1. 2.3.1 Un petit tour du micro-message
      2. 2.3.2 Appliquer le micro aux micro-messages
      3. 2.3.3 Un utilisateur has_many micro-messages
      4. 2.3.4 Hiérarchie des héritages
      5. 2.3.5 Déployer l'application Démo
    4. 2.4 Conclusion
  3. Chapitre 3 Pages statiques courantes
    1. 3.1 Pages statiques
      1. 3.1.1 Pages HTML statiques
      2. 3.1.2 Les pages statiques avec Rails
    2. 3.2 Premiers tests
      1. 3.2.1 Outils de test
        1. Auto-test
      2. 3.2.2 TDD : Rouge, Vert, Refactor
        1. Spork
        2. Rouge
        3. Vert
        4. Refactor
    3. 3.3 Pages (un peu) dynamiques
      1. 3.3.1 Test d'un changement de titre
      2. 3.3.2 Réussir les tests de titre
      3. 3.3.3 Variables d'instance et Ruby embarqué
      4. 3.3.4 Supprimer les répétitions avec les layouts
    4. 3.4 Conclusion
    5. 3.5 Exercices
  4. Chapitre 4 Rails au goût Ruby
    1. 4.1 Motivation
      1. 4.1.1 Un helper pour le titre
      2. 4.1.2 Feuilles de styles (CSS — Cascading Style Sheets)
    2. 4.2 Chaines de caractères et méthodes
      1. 4.2.1 Commentaires
      2. 4.2.2 Chaines de caractères
        1. Impression
        2. Chaines de caractères « apostrophées »
      3. 4.2.3 Objets et passage de message
      4. 4.2.4 Définition de méthode
      5. 4.2.5 Retour à l'« helper » de titre
    3. 4.3 Autres structures de données
      1. 4.3.1 Tableaux et rangs
      2. 4.3.2 Blocs
      3. 4.3.3 Tables de hachage et symboles
      4. 4.3.4 CSS revisitées
    4. 4.4 Classes Ruby
      1. 4.4.1 Constructeurs
      2. 4.4.2 Héritages de classes
      3. 4.4.3 Modifier les classes d'origine
      4. 4.4.4 Classe de contrôleur
      5. 4.4.5 La classe utilisateur
    5. 4.5 Exercices
  5. Chapitre 5 Poursuivre la mise en page
    1. 5.1 Ajout de structure
      1. 5.1.1 Navigation du site
      2. 5.1.2 Personnalisation CSS
      3. 5.1.3 Partiels
    2. 5.2 Liens pour la mise en page
      1. 5.2.1 Test d'intégration
      2. 5.2.2 Routes Rails
      3. 5.2.3 Nommer les routes
    3. 5.3 Inscription de l'utilisateur : une première étape
      1. 5.3.1 Contrôleur Utilisateur
      2. 5.3.2 URL d'inscription
    4. 5.4 Conclusion
    5. 5.5 Exercices
  6. Chapitre 6 Modéliser et afficher les utilisateurs, partie I
    1. 6.1 Modèle utilisateur
      1. 6.1.1 Migrations de la base de données
      2. 6.1.2 Le fichier modèle
        1. Annotation des modèles
        2. Attributs accessibles
      3. 6.1.3 Créer des objets Utilisateur
      4. 6.1.4 Recherche dans les objets Utilisateurs
      5. 6.1.5 Actualisation des objets Utilisateurs
    2. 6.2 Validations utilisateur
      1. 6.2.1 Valider l'existence
      2. 6.2.2 Valider la longueur
      3. 6.2.3 Valider le format
      4. 6.2.4 Valider l'unicité
        1. L'avertissement d'unicité
    3. 6.3 Afficher les utilisateurs
      1. 6.3.1 Débuggage et environnements Rails
      2. 6.3.2 Modèle, Vue et Contrôleur Utilisateur
      3. 6.3.3 Ressource Utilisateurs
        1. Paramètres pour le déboggage
    4. 6.4 Conclusion
    5. 6.5 Exercices
  7. Chapitre 7 Modéliser et afficher les utilisateurs, partie II
    1. 7.1 Mots de passe non sécurisés
      1. 7.1.1 Valider le mot de passe
      2. 7.1.2 Migrer un mot de passe
      3. 7.1.3 Fonction de rappel dans l'Active Record
    2. 7.2 Sécuriser les mots de passe
      1. 7.2.1 Test de mot de passe sécurisé
      2. 7.2.2 Un peu de théorie sur la sécurisation des mots de passe
      3. 7.2.3 Implémenter la méthode has_password?
      4. 7.2.4 Méthode d'authentification
    3. 7.3 Meilleures vues d'utilisateurs
      1. 7.3.1 Tester la page de l'utilisateur (avec factories)
      2. 7.3.2 Un nom et un Gravatar
        1. Un « helper » de Gravatar
      3. 7.3.3 Une barre utilisateur latérale
    4. 7.4 Conclusion
      1. 7.4.1 Dépôt Git
      2. 7.4.2 Déploiement Heroku
    5. 7.5 Exercices
  8. Chapitre 8 Inscription
    1. 8.1 Formulaire d'inscription
      1. 8.1.1 Utiliser form_for
      2. 8.1.2 Le formulaire HTML
    2. 8.2 Échec de l'inscription
      1. 8.2.1 Test de l'échec
      2. 8.2.2 Un formulaire fonctionnel
      3. 8.2.3 Inscription : messages d'erreur
      4. 8.2.4 Filtrer les paramètres d'identification
    3. 8.3 Succès de l'inscription
      1. 8.3.1 Tester le succès de l'inscription
      2. 8.3.2 Le formulaire d'inscription finalisé
      3. 8.3.3 Le message « flash »
      4. 8.3.4 La première inscription
    4. 8.4 Test d'intégration RSpec
      1. 8.4.1 Tests d'intégration avec les styles
      2. 8.4.2 Un échec d'inscription ne devrait pas créer un nouvel utilisateur
      3. 8.4.3 Le succès d'une inscription devrait créer un nouvel utilisateur
    5. 8.5 Conclusion
    6. 8.6 Exercices
  9. Chapitre 9 Connexion, déconnexion
    1. 9.1 Les sessions
      1. 9.1.1 Le contrôleur de session
      2. 9.1.2 Formulaire d'identification
    2. 9.2 Échec de l'identification
      1. 9.2.1 Examen de la soumission du formulaire
      2. 9.2.2 Échec de l'identification (test et code)
    3. 9.3 Succès de l'identification
      1. 9.3.1 L'action create finalisée
      2. 9.3.2 Se souvenir de moi
      3. 9.3.3 Utilisateur courant
    4. 9.4 Déconnexion
      1. 9.4.1 Détruire la session
      2. 9.4.2 Connexion à l'inscription
      3. 9.4.3 Changement des liens de la mise en page
      4. 9.4.4 Test d'intégration de l'identification/déconnexion
    5. 9.5 Conclusion
    6. 9.6 Exercices
  10. Chapitre 10 Actualiser, afficher et supprimer des utilisateurs
    1. 10.1 Actualiser l'utilisateur
      1. 10.1.1 Formulaire de modification
      2. 10.1.2 Permettre les modifications
    2. 10.2 Protéger les pages
      1. 10.2.1 Utilisateurs identifiés requis
      2. 10.2.2 Nécessité du bon utilisateur
      3. 10.2.3 Redirection conviviale
    3. 10.3 Afficher les utilisateurs
      1. 10.3.1 Liste des utilisateurs
      2. 10.3.2 Exemples d'utilisateurs
      3. 10.3.3 Pagination
        1. Test de la pagination
      4. 10.3.4 Restructuration des partiels
    4. 10.4 Supprimer des utilisateurs
      1. 10.4.1 Utilisateurs administrateurs
        1. Révision de attr_accessible
      2. 10.4.2 L'action destroy (« supprimer »)
    5. 10.5 Conclusion
    6. 10.6 Exercices
  11. Chapitre 11 Micro-messages d'utilisateurs
    1. 11.1 Le modèle Micropost (« Micro-message »)
      1. 11.1.1 Le modèle initial
        1. Attributs accessibles
      2. 11.1.2 Associations Utilisateur/micro-messages
      3. 11.1.3 Affinements du micro-message
        1. Portée par défaut
        2. Dépendances de la suppression
      4. 11.1.4 Validations du micro-message
    2. 11.2 Afficher les micro-messages
      1. 11.2.1 Etoffement de la page de l'utilisateur
      2. 11.2.2 Exemples de micro-messages
    3. 11.3 Manipuler les micro-messages
      1. 11.3.1 Contrôle de l'accès
      2. 11.3.2 Créer des micro-messages
      3. 11.3.3 Une proto-alimentation
      4. 11.3.4 Supprimer des micro-messages
      5. 11.3.5 Test de la nouvelle page d'accueil
    4. 11.4 Conclusion
    5. 11.5 Exercices
  12. Chapitre 12 Suivi des utilisateurs
    1. 12.1 Le modèle Relation (Relationship model)
      1. 12.1.1 Un problème du modèle de données (et sa solution)
      2. 12.1.2 Associations Utilisateur/Relations
      3. 12.1.3 Validations
      4. 12.1.4 Auteurs suivis
      5. 12.1.5 Les Lecteurs
    2. 12.2 Une interface web pour les auteurs et les lecteurs
      1. 12.2.1 Exemple de donnée de suivi
      2. 12.2.2 Statistiques et formulaire de suivi
      3. 12.2.3 Pages d'auteurs suivis et de lecteurs
      4. 12.2.4 Un bouton de suivi standard
      5. 12.2.5 Un bouton fonctionnant avec Ajax
    3. 12.3 L'état de l'alimentation
      1. 12.3.1 Motivation et stratégie
      2. 12.3.2 Une première implémentation de peuplement
      3. 12.3.3 Champs d'application, sous-sélections et lambda
      4. 12.3.4 Nouvel état de l'alimentation
    4. 12.4 Conclusion
      1. 12.4.1 Extensions de l'application exemple
        1. Réponses
        2. Notification
        3. Notifications aux lecteurs
        4. Rappel du mot de passe
        5. Confirmation d'inscription
        6. Alimentation RSS
        7. REST API
        8. Recherche
      2. 12.4.2 Guide vers d'autres ressources
    5. 12.5 Exercices

Avant-propos

Ma précédente compagnie (CD Baby) fut une des premières à basculer intégralement vers Ruby on Rails, et à rebasculer aussi intégralement vers PHP (googlez-moi si vous voulez prendre la mesure du drame). On m'a tellement recommandé ce livre Michael Hartl que je n'ai pu faire autrement que de le lire. C'est ainsi que le Tutoriel Ruby on Rails m'a fait revenir à nouveau à Rails.

Bien qu'ayant parcouru de nombreux livres sur Rails, c'est ce tutoriel-là qui m'a véritablement « mis en possession » de Rails. Tout est fait ici « à la manière de Rails » — une manière qui ne m'avait jamais semblé naturelle avant que je ne lise ce livre. C'est aussi le seul ouvrage sur Rails qui met en place, d'un bout à l'autre, un Développement Dirigé par les Tests (Test-Driven Development), une approche que je savais hautement recommandée par les experts mais dont je n'avais jamais compris aussi bien la pertinence que dans ce livre. Enfin, en incluant Git, GitHub et Heroku dans les exemples de la démonstration, l'auteur vous donne vraiment le goût de ce qu'est le développement d'un projet dans la vie réelle. Et le exemples de code ne sont pas en reste.

La narration linéaire adoptée par ce tutoriel est vraiment un bon format. Personnellement, j'ai étudié Le Tutoriel Rails en trois longues journées, en faisant tous les exemples et les exercices proposés à la fin de chaque chapitre. C'est en lisant ce livre du début à la fin, sans sauter la moindre partie, qu'on en tire tout le bénéfice.

Régalez-vous !

Derek Sivers (sivers.org)
Précédemment : Fondateur de CD Baby
Actuellement : Fondateur de Thoughts Ltd.

Remerciements

Ce Tutoriel Ruby on Rails doit beaucoup à mon livre précédent sur Rails, RailsSpace, et donc à mon co-auteur Aurelius Prochazka. J'aimerais remercier Aure à la fois pour le travail qu'il a accompli sur ce précédent livre et pour son soutien pour le présent ouvrage. J'aimerais aussi remercier Debra Williams Cauley, mon éditeur pour les deux ouvrages ; aussi longtemps qu'elle jouera avec moi au baseball, je continuerai d'écrire des livres pour elle.

J'aimerais remercier une longue liste de Rubyistes qui m'ont parlé et inspiré au cours des années : David Heinemeier Hansson, Yehuda Katz, Carl Lerche, Jeremy Kemper, Xavier Noria, Ryan Bates, Geoffrey Grosenbach, Peter Cooper, Matt Aimonetti, Gregg Pollack, Wayne E. Seguin, Amy Hoy, Dave Chelimsky, Pat Maddox, Tom Preston-Werner, Chris Wanstrath, Chad Fowler, Josh Susser, Obie Fernandez, Ian McFarland, Steven Bristol, Giles Bowkett, Evan Dorn, Long Nguyen, James Lindenbaum, Adam Wiggins, Tikhon Bernstam, Ron Evans, Wyatt Greene, Miles Forrest, les gens bien de Pivotal Labs, le gang Heroku, les mecs de thoughtbot et l'équipe de GitHub. Enfin, tellement, tellement, tellement de lecteurs — beaucoup trop pour les citer tous — qui ont contribué par leur rapport de bogues et leurs suggestions durant l'écriture de ce livre, et je tiens à saluer leur aide sans laquelle ce livre ne serait pas ce qu'il est.

À propos de l'auteur

Michael Hartl est programmeur, éducateur et entrepreneur. Il est le co-auteur de RailsSpace, un tutoriel Rails publié en 2007, et a été co-fondateur et développeur en chef de Insoshi, une plateforme de réseau social populaire en Ruby on Rails. Précédement, il a enseigné la théorie et la physique informatique au California Institute of Technology (Caltech), où il a reçu le Lifetime Achievement Award for Excellence en enseignement. Michael est diplômé du Harvard College, a un Ph.D. en physique (un doctorat. NdT) de Caltech, et il est ancien élève du programme des entrepreneurs Y Combinator.

Copyright et license

Le Tutoriel Ruby on Rails : apprendre Rails par l'exemple. Copyright © 2010 par Michael Hartl. Tout le code source du Tutoriel Ruby on Rails est disponible sous la license MIT License et la licence Beerware License.

   Copyright (c) 2010 Michael Hartl

   Permission est accordée, à titre gratuit, à toute personne obtenant
   une copie de ce logiciel et la documentation associée, pour faire des 
   modification dans le logiciel sans restriction et sans limitation des
   droits d’utiliser, copier, modifier, fusionner, publier, distribuer,
   concéder sous licence, et / ou de vendre les copies du Logiciel, et à
   autoriser les personnes auxquelles le Logiciel est meublé de le faire, 
   sous réserve des conditions suivantes:

   L’avis de copyright ci-dessus et cette autorisation doit être inclus
   dans toutes les copies ou parties substantielles du Logiciel.

   LE LOGICIEL EST FOURNI «TEL QUEL», SANS GARANTIE D’AUCUNE SORTE, 
   EXPLICITE OU IMPLICITE, Y COMPRIS, MAIS SANS S’Y LIMITER, LES 
   GARANTIES DE QUALITÉ MARCHANDE, ADAPTATION À UN USAGE PARTICULIER ET
   D’ABSENCE DE CONTREFAÇON. EN AUCUN CAS LES AUTEURS OU TITULAIRES DU
   ETRE TENU RESPONSABLE DE TOUT DOMMAGE, RÉCLAMATION OU AUTRES
   RESPONSABILITÉ, SOIT DANS UNE ACTION DE CONTRAT, UN TORT OU AUTRE,
   PROVENANT DE, DE OU EN RELATION AVEC LE LOGICIEL OU L’UTILISATION OU
   DE TRANSACTIONS AUTRES LE LOGICIEL.
	
/*
 * ------------------------------------------------------------
 * "LA LICENCE BEERWARE" (Révision 42) :
 * Michael Hartl a écrit ce code. Aussi longtemps que vous
 * conservez cette note, vous pouvez faire ce que vous voulez
 * de ce travail. Si nous nous rencontrons un jour, et que vous
 * pensez que ce travail en vaut la peine, vous pourrez me
 * payer une bière en retour.
 * ------------------------------------------------------------
 */

Chapitre 2 Une application Démo

Dans ce chapitre, nous développerons une simple application de démonstration pour révéler un peu de la puissance de Rails. L'objectif est d'obtenir une vue d'ensemble de la programmation Ruby on Rails (et du développement web en général) en générant rapidement une application par l'utilisation du générateur d'échaffaudage (scaffold generators).1 Comme explicité dans le Box 1.1, la suite du livre adoptera une approche opposée à celle-ci, en développant une application étape après étape, en expliquant chaque nouveau concept qui apparaitra, mais pour un aperçu rapide (et quelques rapides gratifications), il n'y a rien de mieux que la construction par échaffaudage. L'application Démo résultant de cette construction nous permettra d'interagir avec elle par le biais des URLs, en nous donnant un aperçu de la structure type d'une application Rails, incluant un premier exemple de l'architecture REST préconisée par Rails.

Comme avec l'Application Exemple que nous développerons par la suite, l'application Démo consistera en des utilisateurs (users) et leur micro-messages (microposts) associés pour constituer une application minimaliste de type Twitter. Les fonctionnalités seront pour le moins sous-exploitées, et beaucoup d'étapes du développement vous paraitront tout simplement magiques, mais ne vous inquiétez pas : l'Application Exemple complète développera une application similaire depuis le tout départ au chapitre 3, et je fournirai d'abondantes références concernant tous les points abordés. Dans le même temps, soyez patient et gardez la foi — l'objectif de ce tutoriel est de vous conduire au-delà de la superficialité de l'approche par échaffaudage pour acquérir une compréhension profonde de Rails.

2.1 Planifier l'application

Dans cette section, nous allons poser les plans de notre Application Démo. Comme dans la section 1.2.3, nous commencerons par générer le squelette de l'application en utilisant la commande rails :

$ cd ~/rails_projects
$ rails new demo_app
$ cd demo_app

Maintenant, utilisons l'éditeur de texte pour actualiser le contenu du fichier Gemfile utile à Bundler avec le code de l'extrait 2.1.

Extrait 2.1. Un fichier Gemfile pour l'application Démo.
source 'http://rubygems.org'

gem 'rails', '3.0.7'
gem 'sqlite3-ruby', '1.3.2', :require => 'sqlite3'

(Rappelez-vous de la section 1.2.4 : vous pouvez avoir besoin de la version 1.2.5 du gem sqlite3-ruby si vous êtes sous OS X Leopard.) Nous installons alors et incluons les gems en utilisant bundle :

$ bundle install

Pour finir, nous initialiserons un repository Git et ferons le premier dépôt :2

$ git init
$ git add .
$ git commit -m "Initial commit"
create_demo_repo
Illustration 2.1: Créer un repository pour l'application Démo sur GitHub. (taille normale)

Vous pouvez aussi, optionnellement, créer un nouveau repository (Illustration 2.1) et le « pusher » vers GitHub :

$ git remote add origin git@github.com:<username>/demo_app.git
$ git push origin master

Nous sommes prêts à présent à construire l'application elle-même. La première étape typique quand on fabrique une application web est de créer un modèle de données, qui est une représentation de la structure nécessaire à notre application. Dans notre cas, l'application Démo sera un micro-blog, avec uniquement des utilisateurs et de courts messages. Nous commencerons donc par le modèle de données pour les utilisateurs de l'application (Section 2.1.1), et nous ajouterons ensuite un modèle de données pour les micro-messages (microposts) (Section 2.1.2).

2.1.1 Modéliser les utilisateurs

Il y a autant de modèles de données utilisateurs sur le web qu'il y a de formulaires d'inscription ; nous adopterons définitivement une approche minimaliste. Les utilisateurs de notre application Démo possèderont un identifiant unique appelé id, un nom affiché publiquement (de type chaine de caractères, string) et une adresse mail (de type également string) qui servira de double au nom d'utilisateur (username). Un résumé du modèle de données pour les utilisateurs (en anglais) est visible dans l' illustration 2.2.

demo_user_model
Illustration 2.2: Le modèle de données pour les utilisateurs.

Comme nous le verrons en commençant la section 6.1.1, le label users (utilisateurs) dans l'illustration 2.2 correspond à une table dans la base de données, et les attributs id, nom (name en anglais) et email correspondent aux colonnes de cette table.

2.1.2 Modéliser les micro-messages

Le cœur du modèle de données des micro-messages (microposts) est souvent plus simple que celui des utilisateurs : un micro-message possède seulement un champ id (identifiant) et un champ content (contenu) pour le texte du micro-message (de type string).3 Demeure cependant quelques complications : nous voulons associer chaque micro-message à un utilisateur particulier ; nous accomplirons cela en enregistrant le user_id (identifiant d'utilisateur) de l'auteur du message. Le résultat apparait dans l'illustration 2.3.

demo_micropost_model
Illustration 2.3: Le modèle de données pour les micro-messages.

Nous verrons à la section 2.3.3 (et plus profondément au chapitre 11) comment cet attribut user_id nous permet d'exprimer de façon succinte le fait qu'un utilisateur est potentiellement associé à plusieurs micro-messages.

2.2 La ressouce Utilisateur (Users)

Dans cette section, nous allons implémenter le modèle de données utilisateurs de la section 2.1.1, en même temps qu'une interface web pour ce modèle. La combinaison des deux constituera une ressource utilisateurs (Users resource) qui nous permettra de penser les utilisateurs comme des objets (objects) qui peuvent être créés, consultés, actualisés et supprimés sur le web via le protocole HTTP (le traducteur tient à préciser qu'il s'inscrit en faux contre le fait de « penser les utilisateurs comme des objets » :-).NdT).

Comme promis dans l'introduction, notre ressource utilisateurs sera créée par un programme de génération d'échaffaudage, présent de façon standard dans chaque projet Rails. L'argument de la commande scaffold (échaffaudage) est la version singulier du nom de la ressource (dans ce cas : User), auquel on peut ajouter en paramètres optionnels les attributs du modèle de données :4

$ rails generate scaffold User nom:string email:string
      invoke  active_record
      create    db/migrate/20100615004000_create_users.rb
      create    app/models/user.rb
      invoke    test_unit
      create      test/unit/user_test.rb
      create      test/fixtures/users.yml
       route  resources :users
      invoke  scaffold_controller
      create    app/controllers/users_controller.rb
      invoke    erb
      create      app/views/users
      create      app/views/users/index.html.erb
      create      app/views/users/edit.html.erb
      create      app/views/users/show.html.erb
      create      app/views/users/new.html.erb
      create      app/views/users/_form.html.erb
      invoke    test_unit
      create      test/functional/users_controller_test.rb
      invoke    helper
      create      app/helpers/users_helper.rb
      invoke      test_unit
      create        test/unit/helpers/users_helper_test.rb
      invoke  stylesheets
      create    public/stylesheets/scaffold.css

En ajoutant nom:string et email:string, nous nous sommes arrangés pour que le modèle de données User prenne la forme définie dans l'illustration 2.2 (notez qu'il n'y a nul besoin d'inclure un paramètre pour l'attribut id : il est créé automatiquement par Rails.5)

Pour pouvoir utiliser l'application Démo, nous avons d'abord besoin de migrer (migrate) la base de données en utilisant Rake (Box 2.1):

$ rake db:migrate
==  CreateUsers: migrating ====================================================
-- create_table(:users)
   -> 0.0017s
==  CreateUsers: migrated (0.0018s) ===========================================

Cette procédure actualise simplement la base de données avec notre nouveau modèle de données utilisateurs (users). Nous en apprendrons plus à propos des migrations de la base de données au début de la section 6.1.1.

Cela fait, nous pouvons lancer le serveur web local en utilisant la commande rails s, qui est le raccourci de la commande rails server:

$ rails s

L'application Démo devrait maintenant être accessible à l'adresse http://localhost:3000/ de votre navigateur.

2.2.1 Un tour de l'utilisateur

Rejoindre l'url racine http://localhost:3000/ affichera la même page Rails par défaut présentée dans l'illustration 1.3, mais en générant l'échaffaudage de la ressource utilisateurs nous avons également créé un grand nombre de pages permettant de manipuler ces utilisateurs. Par exemple, la page pour afficher les utilisateurs, en ajoutant /users (http://localhost:3000/users) ou et la page pour créer un nouvel utilisateur en ajoutant /users/new.6 La suite de cette section présentera un tour rapide de ces pages utilisateurs. En suivant ce tour, il peut être utile de se référer à la table 2.1, qui présente la correspondance entre les pages et les URLs respectives.

URLActionPage
/usersindexPage listant les utilisateurs
/users/1showPage de l'utilisateur d'id 1
/users/newnewPage pour créer un nouvel utilisateur
/users/1/editeditPage d'édition de l'utilisateur d'id 1
Table 2.1: Correspondance entre pages et URLs de la ressource Users.

Nous commençons avec la page listant tous les utilisateurs de notre application, appelée index ; comme nous pouvons nous y attendre, il n'y a pour le moment aucun utilisateur (illustration 2.4).

demo_blank_user_index_rails_3
Illustration 2.4: La page index initiale de la ressource utilisateurs (/users). (taille normale)

Pour créer un nouvel utilisateur, visitons la page new, de l'illustration 2.5 (au chapitre 8, cette page deviendra la page d'inscription).

demo_new_user_rails_3
Illustration 2.5: La page de nouvel utilisateur (/users/new). (taille normale)

Nous pouvons créer un nouvel utilisateur en entrant les valeurs du nom et de l'email dans les champs de texte correspondants et en cliquant ensuite sur le bouton de création (Create User). Le résultat est la page d'utilisateur show (afficher) de l'illustration 2.6 la présente (le message vert de bienvenue est obtenu en utilisant la messagerie flash qui sera abordée dans la section 8.3.3). Notez que l'URL est à présent /users/1 ; comme vous pouvez vous en douter, le nombre 1 est l'identifiant de l'utilisateur (l'attribut id) de l'illustration 2.2. À la section 7.3, cette page deviendra la page du profil de l'utilisateur.

demo_show_user_rails_3
Illustration 2.6: La page affichant l'utilisateur (/users/1 — version anglaise). (taille normale)

Pour modifier les informations de l'utilisateur, nous nous rendons sur la page edit (modifier) (Illustration 2.7). En modifiant les informations de l'utilisateur et en cliquant sur le bouton d'actualisation (Update User), nous changerons les informations dans l'application Démo (Illustration 2.8) (comme nous le verrons en détail en abordant le chapitre 6, les données de l'utilisateur sont stockées dans la base de données). Nous ajouterons les fonctionnalités edit/update à l'Application Exemple dans la section 10.1.

demo_edit_user_rails_3
Illustration 2.7: La page d'édition de l'utilisateur (/users/1/edit — version anglaise). (taille normale)
demo_update_user_rails_3
Illustration 2.8: Un utilisateur dont les informations ont été actualisées. (taille normale)

Nous allons maintenant créer un second utilisateur en revisitant la page new et en soumettant un second jeu d'informations (Il peut être utile de cliquer d'abord le lien « Back » pour revenir à la liste des utilisateurs. NdT) ; l'index (la liste) en résultant est présenté dans l'illustration 2.9. La section 10.3 permettra de polisser cette page d'index affichant tous les utilisateurs.

demo_user_index_two_rails_3
Illustration 2.9: La page d'index des utilisateurs (/users) avec un autre utilisateur. (taille normale)

Ayant vu comment créer, afficher et éditer les utilisateurs, nous en arrivons maintenant à voir comment les détruire (Illustration 2.10). Vous devriez pouvoir vérifier qu'un clic sur le lien mis en exergue dans l'illustration 2.10 détruit le second utilisateur, réduisant la page d'index à un seul utilisateur (si cela ne fonctionne pas, assurez-vous que JavaScript est bien activé dans votre navigateur ; Rails utilise JavaScript pour exécuter la requête de destruction d'un utilisateur). La section 10.4 ajoute la suppression de l'utilisateur à l'Application Exemple, en prenant soin de restreindre l'usage de cette fonctionnalité aux seuls administrateurs du site (utilisateurs de classe « administrateur »).

demo_destroy_user_rails_3
Illustration 2.10: Destruire un utilisateur. (taille normale)

2.2.2 MVC en action

Maintenant que nous avons accompli un rapide aperçu de la ressource utilisateurs (Users), examinons une partie singulière de cette ressource dans le contexte du concept Modèle-Vue-Contrôleur introduit à la section 1.2.6. Notre stratégie sera de décrire le résultat d'un « hit » typique de navigateur — une visite à la page d'index des utilisateurs, à l'adresse /users — en terme de MVC (Illustration 2.11).

mvc_detailed
Illustration 2.11: Un diagramme détaillé du MVC dans Rails. (taille normale)
  1. Le navigateur reçoit une requête pour l'URL /users ;
  2. Rails route (dirige) /users vers une action index dans le contrôleur Users (Utilisateurs) ;
  3. L'action index demande au modèle User de récupérer tous les utilisateurs (User.all) ;
  4. Le modèle User tire tous les utilisateurs de la base de données ;
  5. Le modèle User retourne au contrôleur la liste des utilisateurs ;
  6. Le contrôleur place les utilisateurs dans la variable @users, variable qui est passée à la vue index ;
  7. La vue utilise le code Ruby embarqué pour rendre la page au format HTML ;
  8. Le contrôleur renvoie le code HTML au navigateur, qui affiche enfin la page.7

Nous commençons par une requête provenant du navigateur — par exemple, après avoir tapé une URL dans la barre d'adresse du navigateur ou avoir cliqué un lien (étape  1 de l'illustration 2.11). Cette requête atteint le routeur Rails (étape 2), qui la dispatche vers l'action de contrôleur adéquate basée sur l'URL (et, comme nous le verrons dans le Box 3.1, le type de requête). Le code pour créer la carte des URLs utilisateur vers les actions de contrôleur de la ressource Users est présenté dans l'illustration 2.2 ;8 ce code définit effectivement la table des paires URL/action définies dans la table 2.1.

Extrait 2.2. Le routage Rails, avec une règle pour la ressource Users.
config/routes.rb
DemoApp::Application.routes.draw do
  resources :users
  .
  .
  .
end

Les pages du tour de la section 2.2.1 correspondent aux actions dans le controller des utilisateurs , qui est une collection d'actions correspondantes ; le contrôleur généré par l'écheffaudage est présenté schématiquement dans l'extrait 2.3. Remarquez la notation class UsersController < ApplicationController ; c'est un exemple de classe Ruby avec héritage (nous discuterons brièvement des héritages de classe à la section 2.3.4 et couvrirons ces deux sujets plus en détail à la section 4.4).

Extrait 2.3. Schéma du contrôleur utilisateurs (UsersController).
app/controllers/users_controller.rb
class UsersController < ApplicationController

  def index
    .
    .
    .
  end

  def show
    .
    .
    .
  end

  def new
    .
    .
    .
  end

  def create
    .
    .
    .
  end

  def edit
    .
    .
    .
  end

  def update
    .
    .
    .
  end

  def destroy
    .
    .
    .
  end
end

Vous pouvez noter qu'il y a plus d'actions que de pages ; les actions index, show, new et edit correspondent toutes à la section 2.2.1, mais on trouve en supplément les actions create, update, et destroy. Ces actions ne retournent pas, typiquement, de pages (bien qu'elles puissent le faire dans certains cas) ; leur rôle principal est plutôt de modifier les informations des utilisateurs dans la base de données. Cette liste complète des actions du contrôleur, résumée dans la table 2.2, représente l'implémentation de l'architecture REST en Rails (Box 2.2). Notez, dans la table 2.2, qu'il y a certains chevauchements dans les URLs ; par exemple, les actions utilisateur show (afficher) et update (actualiser) correspondent toutes deux à l'URL /users/1. La distinction entre l'une et l'autre se fait grâce à la méthode de requête HTTP (HTTP request method) à laquelle elles répondent. Nous en apprendrons plus à propos de ces méthodes de requête HTTP à la section 3.2.2.

Requête HTTPURLActionPropos
GET/usersindexpage listant tous les utilisateurs
GET/users/1showpage affichat l'utilisateur d'id 1
GET/users/newnewpage pour créer un nouvel utilisateur
POST/userscreatecréer un nouvel utilisateur
GET/users/1/editeditpage pour éditer l'utilisateur d'id 1
PUT/users/1updateactualiser l'utilisateur d'id 1
DELETE/users/1destroydétruire l'utilisateur d'id 1
Table 2.2: Routages RESTful fournit par la ressource Users dans l'extrait 2.2.

Pour examiner la relation entre contrôleur utilisateur et modèle utilisateur, concentrons-nous sur une version simplifiée de l'action index vue dans l'extrait 2.4.9

Extrait 2.4. L'action utilisateur index simplifiée pour l'application Démo.
app/controllers/users_controller.rb
class UsersController < ApplicationController

  def index
    @users = User.all
  end
  .
  .
  .
end

Cette action index implémente la ligne @users = User.all (étape 3), qui demande au modèle utilisateur de récupérer de la base de données une liste de tous les utilisateus (étape 4), et de les placer dans une variable @users (prononcez “hate-iou-zeur-ze”) (étape 5). Le modèle utilisateur lui-même apparait dans l''extrait 2.5 ; bien que plutôt ordinaire, il arrive équipé d'un grand nombre de fonctionnalités grâce à l'héritage de classe (section 2.3.4 et section 4.4). En particulier, en utilisant la librairie Rails de nom Active Record, le code de l'extrait 2.5 se débrouille pour que User.all retourne tous les utilisateurs.

Extrait 2.5. Le modèle Utilisateur (User) pour l'application Démo.
app/models/user.rb
class User < ActiveRecord::Base
end

Une fois la variable @users renseignée, le contrôleur appelle la vue (view) (étape 6), vue de l'extrait 2.6. Les variables commençant par le caractère @, appelées variables d'instance (instance variables), sont automatiquement accessibles dans la vue ; dans ce cas précis, la vue index.html.erb de l'extrait 2.6 boucle itérativement sur la liste @users et retourne une ligne HTML à chaque itération.10

Extrait 2.6. La vue pour l'index utilisateurs (vous n'êtes pas supposés le comprendre tout de suite).
app/views/users/index.html.erb
<h1>Liste des utilisateurs</h1>

<table>
  <tr>
    <th>Nom</th>
    <th>Email</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>

<% @users.each do |user| %>
  <tr>
    <td><%= user.nom %></td>
    <td><%= user.email %></td>
    <td><%= link_to 'Montrer', user %></td>
    <td><%= link_to 'Modifier', edit_user_path(user) %></td>
    <td><%= link_to 'Détruire', user, :confirm => 'Êtes-vous certain ?',
:method => :delete %></td>
  </tr>
<% end %>
</table>

<br />

<%= link_to 'New User', new_user_path %>

La vue convertit son contenu en code HTML (étape 7), qui est alors retourné par le contrôleur au navigateur qui va l'afficher (étape 8).

2.2.3 Faiblesse de cette ressource utilisateur

Bien qu'excellent pour donner un aperçu général de Rails, la ressource Utilisateurs de l'échaffaudage souffre d'un certain nombre de faiblesses.

  • Pas de validation de données. Notre modèle utilisateur accepte aussi bien et sans broncher les noms vides ou les adresses mail invalides ;
  • Pas d'authentification. Nous n'avons aucune notion d'identification ou de déconnexion, et aucun moyen de prévenir un utilisateur quelconque d'exécuter une opération quelconque ;
  • Pas de tests. Techniquement, ça n'est pas tout à fait juste — l'échaffaudage inclut des tests rudimentaires — mais les test générés automatiquement son laids et rigides, et ils ne testent pas la validation des données, l'authentification ou autres besoins personnalisés ;
  • Pas de mise en page. Il n'y a pas de charte graphique ;
  • Pas de compréhension réelle. Si vous comprenez le code de l'échaffaudage, alors vous n'avez certainement aucune besoin de lire ce livre.

2.3 La ressource micro-messages

Après avoir généré et exploré la ressource utilisateurs, nous nous tournons à présent vers la ressource associée des micro-messages. Tout au long de cette section, je recommande de comparer les éléments de la ressource micro-messages avec les éléments analogues de la ressource utilisateur de la section 2.2 ; vous devriez constater que les deux ressources s'apparente l'une à l'autre en de nombreux points. La structure RESTful des applications Rails est mieux « absorbée » grâce à cette sorte de répétition formelle ; vraiment, constater le parallèle de structure entre les ressources Utilisateurs et Micro-messages, même à cette étape peu avancée, est une des raisons d'être première de ce chapitre (comme nous le verrons, l'écriture d'applications plus solides que l'exemple enfantin de ce chapitre demande des efforts considérables — nous ne reverrons pas la ressource Micro-messages avant le chapitre 11 — et je ne voulais pas retarder son introduction aussi loin).

2.3.1 Un petit tour du micro-message

Comme avec la ressource utilisateurs, nous allons générer le code de l'échaffaudage de la ressource des micro-messages (Microposts) en utilisant le code rails generate scaffold, dans ce cas en implémentant le modèle de données de l'illustration 2.3:11

$ rails generate scaffold Micropost content:string user_id:integer
      invoke  active_record
      create    db/migrate/20100615004429_create_microposts.rb
      create    app/models/micropost.rb
      invoke    test_unit
      create      test/unit/micropost_test.rb
      create      test/fixtures/microposts.yml
       route  resources :microposts
      invoke  scaffold_controller
      create    app/controllers/microposts_controller.rb
      invoke    erb
      create      app/views/microposts
      create      app/views/microposts/index.html.erb
      create      app/views/microposts/edit.html.erb
      create      app/views/microposts/show.html.erb
      create      app/views/microposts/new.html.erb
      create      app/views/microposts/_form.html.erb
      invoke    test_unit
      create      test/functional/microposts_controller_test.rb
      invoke    helper
      create      app/helpers/microposts_helper.rb
      invoke      test_unit
      create        test/unit/helpers/microposts_helper_test.rb
      invoke  stylesheets
   identical    public/stylesheets/scaffold.css

Pour actualiser notre base de données avec le nouveau modèle de données, il est nécessaire de demander une nouvelle migration comme dans la section 2.2 :

$ rake db:migrate
==  CreateMicroposts: migrating ===============================================
-- create_table(:microposts)
   -> 0.0023s
==  CreateMicroposts: migrated (0.0026s) ======================================

Maintenant nous sommes en mesure de créer des micro-messages de la même façon que nous avons créé des utilisateurs dans la section 2.2.1. Comme vous pouvez vous en douter, le générateur d'échaffaudage a actualisé le fichier de routage Rails avec des règles pour la ressource Microposts (Micro-messages), comme le montre l'extrait 2.7.12 Comme pour les utilisateurs, la règle des routages resources :microposts dirige les URLs des micro-messages vers les actions correspondantes dans le contrôleur Microposts, suivant la table 2.3.

Extrait 2.7. Le routage Rails, avec une nouvelle règle pour les ressources Microposts.
config/routes.rb
DemoApp::Application.routes.draw do
  resources :microposts
  resources :users
  .
  .
  .
end
Requête HTTPURLActionPage ou Opération
GET/micropostsindexPage listant tous les micro-messages
GET/microposts/1showPage affichant le micro-message d'id 1
GET/microposts/newnewPage créant une nouveau micro-message
POST/micropostscreateCrée le nouveau micro-message
GET/microposts/1/editeditPage pour éditer le micro-message d'id 1
PUT/microposts/1updateActualiser le micro-message d'id 1
DELETE/microposts/1destroyDétruire le micro-message d'id 1
Table 2.3: Routes RESTful fournies par la ressource Microposts de l'extrait 2.7.

La contrôleur Microposts lui-même apparait dans sa forme schématique dans l'extrait 2.8. Notez que, hormis le MicropostsController à la place du UsersController, l'extrait 2.8 est identique au code de l'extrait 2.3. C'est une conséquence directe de l'architecture REST commune aux deux ressources.

Extrait 2.8. Le contrôleur Microposts en forme schématique.
app/controllers/microposts_controller.rb
class MicropostsController < ApplicationController

  def index
    .
    .
    .
  end

  def show
    .
    .
    .
  end

  def new
    .
    .
    .
  end

  def create
    .
    .
    .
  end

  def edit
    .
    .
    .
  end

  def update
    .
    .
    .
  end

  def destroy
    .
    .
    .
  end
end

Pour faire quelques micro-messages, nous entrons les informations dans la page de création des micro-messages, /microposts/new de l'illustration 2.12.

demo_new_micropost_rails_3
Illustration 2.12: La page de création du micro-message (/microposts/new). (taille normale)

À ce stade, poursuivez et créez un ou deux micro-messages, en vous assurant que l'un au moins possède un user_id de 1 pour correspondre à l'identifiant du premier utilisateur créé dans la section 2.2.1. Le résultat devrait s'apparenter à celui de l'illustration 2.13.

demo_micropost_index_rails_3
Illustration 2.13 : La page d'index des micro-messages (/microposts). (taille normale)

2.3.2 Appliquer le micro aux micro-messages

Tout micro-message digne de ce nom devrait avoir les moyens de faire respecter la longueur de son texte. Implémenter cette contrainte en Rails est très simple grâce aux validations ; pour accepter les micro-messages d'au plus 140 caractères (à la Twitter), nous utilisons une validation de longueur (length). À ce stade, vous devriez ouvrir le fichier app/models/micropost.rb dans votre éditeur de texte ou votre IDE et le remplir avec le contenu de l'extrait 2.9 (l'utilisation de validates dans l'extrait 2.9 est caractéristique de la version 3 de Rails ; si vous avez travaillé précédemment avec Rails 2.3, vous devriez comparer cet usage à l'utilisation de l'ancien validates_length_of).

Extrait 2.9. Contraindre la longueur maximale des micro-messages à 140 caractères avec la validation de longueur.
app/models/micropost.rb
class Micropost < ActiveRecord::Base
  validates :content, :length => { :maximum => 140 }
end

Le code de l'extrait 2.9 peut sembler plutôt mystérieux — nous couvrirons la question des validations plus profondément à la section 6.2 — mais ses effets sont significatifs si nous nous rendons à la page de création des micro-messages et que nous entrons un messages de plus de 140 caractères. Comme nous pouvons le voir dans l'illustration 2.14, Rails renvoie un message d'erreur indiquant que le contenu du message est trop long (nous en apprendrons plus à propos des messages d'erreur à la section 8.2.3.)

micropost_length_error_rails_3
Illustration 2.14 : Message d'erreur à l'échec de la création d'un message. (taille normale)

2.3.3 Un utilisateur possède plusieurs micro-messages

L'une des fonctionnalités les plus puissantes de Rails est la possibilité de former des associations entre plusieurs modèles de données. Dans le cas de notre modèle utilisateur, chaque utilisateur produit potentiellement plusieurs messages. Nous pouvons exprimer cela en code en actualisant les modèles User (Utilisateur) et Micropost (Micro-message) conformément à l'extrait 2.10 et l'extrait 2.11.

Extrait 2.10. Un utilisateur possède plusieurs micro-messages.
app/models/user.rb
class User < ActiveRecord::Base
  has_many :microposts
end
Extrait 2.11. Un micro-message appartient à un utilisateur.
app/models/micropost.rb
class Micropost < ActiveRecord::Base
  belongs_to :user

  validates :content, :length => { :maximum => 140 }
end

Nous pouvons visualiser le résultat de cette association dans l'illustration 2.15. Grâce à la colonne user_id de la table microposts, Rails (en utilisant Active Record) peut déduire les micro-messages associés à chaque utilisateur.

micropost_user_association
Illustration 2.15 : L'association entre les micro-messages et les utilisateurs.

Au chapitre 11 et au chapitre 12, nous utiliserons l'association entre utilisateurs et micro-messages pour afficher tous les micro-messages d'un utilisateur donné et pour construire une alimentation en messages à la façon de Twitter. Pour le moment, nous pouvons examiner les implications de cette association en utilisant la console, qui est un outil utile pour interagir avec les applications Rails. Nous invoquons tout d'abord la console avec rails console en ligne de commande, puis récupérons le premier utilisateur dans la base de données en tapant User.first (en plaçant le résultat dans la variable first_user — premier_utilisateur) :13

$ rails console
>> first_user = User.first
=> #<User id: 1, nom: "Michael Hartl", email: "michael@example.org",
created_at: "2010-04-03 02:01:31", updated_at: "2010-04-03 02:01:31">
>> first_user.microposts
=> [#<Micropost id: 1, content: "First micropost!", user_id: 1, created_at:
"2010-04-03 02:37:37", updated_at: "2010-04-03 02:37:37">, #<Micropost id: 2,
content: "Second micropost", user_id: 1, created_at: "2010-04-03 02:38:54",
updated_at: "2010-04-03 02:38:54">]
>> exit

(J'ajoute la dernière ligne pour montrer comment sortir de la console Rails, et sur la plupart des systèmes vous pouvez taper Ctrl-d pour obtenir le même résultat). Ici nous avons obtenu les micro-messages de l'utilisateur en utilisant le code first_user.microposts : grâce à ce code, Active Record retourne automatiquement tous les micro-messages dont le user_id est égal à l'identifiant du first_user (1, dans ce cas précis). Nous en apprendrons plus à propos des facilités des associations avec Active Record au chapitre 11 et au chapitre 12.

2.3.4 Hiérarchie des héritages

Nous terminons notre discussion sur l'application Démo par une brève description des hiérarchies des classes contrôleur (controller) et modèle (model) dans Rails. Cette discussion n'aura vraiment de sens pour vous que si vous possédez une expérience de la programmation orientée objet (OOP) ; si vous n'avez pas étudié l'OOP, sentez-vous libre de sauter cette section. En particulier, si vous n'êtes pas familier des classes (en discussion à la section 4.4), je vous suggère de revenir ultérieurement à cette section.

Nous commençons par l'héritage de structure pour les modèles. En comparant l'extrait 2.12 et l'extrait 2.13, vous voyez que le modèle User (Utilisateur) tout comme le modèle Micropost (Micro-message) hérite de ActiveRecord::Base (via le signe <), qui est la classe de base pour les modèles fournis par ActiveRecord ; un diagramme résumant cette relation est présenté par l'illustration 2.16. C'est en héritant de ActiveRecord::Base que nos modèles d'objet acquièrent la faculté de communiquer avec la base de données, traitent les colonnes de cette base comme des attributs Ruby, etc.

Extrait 2.12. La classe-objet User, avec héritage.
app/models/user.rb
class User < ActiveRecord::Base
  .
  .
  .
end
Extrait 2.13. La classe-objet Micropost, avec héritage.
app/models/micropost.rb
class Micropost < ActiveRecord::Base
  .
  .
  .
end
demo_model_inheritance
illustration 2.16: La hiérarchie d'héritage pour les modèles User et Micropost.

La structure héritée pour les contrôleurs est juste un peu plus complexe. En comparant l'extrait 2.14 avec l'extrait 2.15, nous voyons que le contrôleur Users (Utilisateurs) comme le contrôleur Microposts (Micro-messages) héritent du contrôleur Application. En examinant l'extrait 2.16, nous voyons que ApplicationController lui-même hérite de ActionController::Base ; c'est la classe-objet de base pour les contrôleurs fournis par la librairie Rails « Action Pack ». Les relations entre ces classes sont présentées dans l'illustration 2.17.

Extrait 2.14. La classe-objet UsersController, avec l'héritage.
app/controllers/users_controller.rb
class UsersController < ApplicationController
  .
  .
  .
end
Extrait 2.15. La classe-objet MicropostsController, avec héritage.
app/controllers/microposts_controller.rb
class MicropostsController < ApplicationController
  .
  .
  .
end
Extrait 2.16. La classe-objet ApplicationController, avec héritage.
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  .
  .
  .
end
demo_controller_inheritance
Illustration 2.17: La hiérarchie d'héritage pour les contrôleurs Users (Utilisateurs) et Microposts (Micro-messages).

Comme pour l'héritage du modèle, en héritant en fin de compte de ActionController::Base, le contrôleur Users tout comme le contrôleur Microposts héritent d'un grand nombre de fonctionnalités, telles que la capacité de manipuler les objets du modèle, de filtrer les requêtes HTTP entrantes, et de rendre les vues en code HTML. Puisque tous les contrôleurs Rails héritent de ApplicationController, les règles définies dans le contrôleur de l'application sont automatiquement appliquées à toutes les actions à l'intérieur de l'application. Par exemple, nous verrons dans la section 8.2.4 comment une règle définie dans le contrôleur de l'application nous permet de filtrer tous les mots de passe de tous les fichiers, évitant ainsi l'éventualité d'un sérieux trou de sécurité.

2.3.5 Déployer l'application Démo

Avec l'achèvement de la ressource Micropost, il est temps à présent de « pusher » le repository vers GitHub :14

$ git add .
$ git commit -a -m "Fin de l'application demo"
$ git push

Vous pouvez également déployer l'application démo vers Heroku :

$ heroku create
$ git push heroku master
$ heroku rake db:migrate

(Si cela ne fonctionne pas chez vous, voyez la note juste au-dessus de l'extrait 1.8 pour une solution possible) Remarquez la ligne finale ici, qui lance la migration de la base de données sur le serveur Heroku. Cela actualise la base de données sur Heroku avec le modèle de données user/micropost nécessaire. Si vous voulez également « pusher » les données (data), vous pouvez le faire en utilisant le gem taps et db:push :

$ [sudo] gem install taps
$ heroku db:push

2.4 Conclusion

Nous sommes arrivés à la fin de la « vue d'en haut » d'une application Rails. L'application Démo développée dans ce chapitre possède plusieurs points forts et une multitude de faiblesses.

Points forts

  • Aperçu général de Rails ;
  • Introduction au principe M-V-C ;
  • Avant goût de l'architecture REST ;
  • Initiation à la modélisation de données ;
  • Une application à base de données fonctionnelle, en mode production.15

Points faibles

  • Pas de mise en forme ni de style ;
  • Pas de pages statiques (telles que la page d'accueil ou l'aide) ;
  • Pas de mot de passe utilisateur ;
  • Pas d'avatars utilisateurs ;
  • Pas d'identification ;
  • Pas de sécurité ;
  • Pas d'association automatique entre utilisateur et micro-messages ;
  • Pas de notion de suivi de message (du côté auteur comme lecteur) ;
  • Pas d'alimentation de micro-messages ;
  • Pas de « Développement Dirigé par le Test » ;
  • Pas de réelle compréhension…

La suite de ce tutoriel s'appuie sur les points forts pour continuer de développer et se consacre à éliminer systématiquement tous les points faibles.

  1. Je vous conjure de ne pas regarder de trop prêt le code généré ; à ce niveau, il ne pourrait que vous embrouiller. 
  2. Rappelez-vous que la commande rails produit un fichier .gitignore par défaut, mais suivant votre système vous pourrez trouver le fichier augmenté de l'extrait 1.5 plus efficient. 
  3. En modélisant de plus longs messages, comme ceux d'un blog, vous devrez utiliser le type text plutôt que le type string
  4. Le nom de l'échaffaudage respecte la convention des modèles (models), qui sont singulier, contrairement aux ressources et aux contrôleurs, qui sont pluriel. Ainsi, nous utilisons User (Utilisateur) plutôt que Users (Utilisateurs). 
  5. L'identifiant de l'utilisateur est nécessaire comme clé primaire dans la base de données. 
  6. Puisque le port http://localhost:3000 de l'adresse est implicite chaque fois que nous développons en local, je l'omettrai à partir de maintenant. 
  7. Certaines sources indiquent que la vue retourne le code HTML directement au navigateur (via un serveur web comme Apache ou Nginx). Indépendamment des détails d'implémentation, je préfère penser le contrôleur comme un hub central au travers duquel passe toutes les informations de l'application. 
  8. La notation étrange :users est une notation symbolique, comme nous le verrons à la section 4.3.3
  9. Le code de l'échaffaudage est laid et troublant, donc je l'ai supprimé. 
  10. Rappelez-vous que vous n'êtes pas supposé comprendre ce code tout de suite. Il est indiqué uniquement en guise d'illustration. 
  11. Comme pour l'échaffaudage de l'utilisateur, le générateur d'échaffaudage pour les micro-messages suit la convention du singulier des modèles Rails ; ainsi, nous utilisons generate Micropost
  12. Le code de l'échaffaudage peut comprendre des retours à la ligne supplémentaires par rapport à l'extrait 2.7 ; ça n'est pas important, puisque Ruby ignore ces retours à la ligne. 
  13. Votre invite de console présentera probablement quelque chose comme ruby-1.9.2-head >, mais j'utiliserai >> de telle sorte que l'invite ne soit pas liée à une version de Ruby spécifique. 
  14. D'ordinaire, vous devriez faire des dépôts plus petits et plus fréquents, mais pour le propos de ce chapitre, un simple dépôt important conviendra parfaitement. 
  15. Si vous déployez votre site sur Heroku à la section 2.3.5