« Ruby on Rails : Vues & Contrôleur » Le 16 février 2009 Ruby on Rails

Concentrons nos efforts d’aujourd’hui sur la bonne compréhension des mécanismes qui sont à la base du fonctionnement de Ruby On Rails, framework que je me suis proposé de présenter en plusieurs articles dans celui-ci, qui annonce le plan des festivités à venir. Si vous ne disposez pas encore d’un environnement dans lequel développer, n’hésitez pas à consulter mon précédent article, dans lequel je décris comment installer Rails sur votre machine sous Linux ou Windows et le déployer sur votre serveur grâce à Phusion Passenger ;) !

Un contrôleur ? Une vue ?

Comme vous le savez peut-être, Rails repose comme la majeure partie des frameworks web (avec quelques variantes tout de même) sur le paradigme MVC : ces trois lettres sont _la_ clé, le moyen de concevoir et développer en équipe des applications que vous n’aurez aucun mal à faire évoluer par la suite. Le beurre et l’argent du beurre en somme ? Presque.

Pour résumer sans rentrer dans les subtilités de l’affaire, il s’agit de séparer votre développement en trois couches plus ou moins perméables : le Modèle, la Vue et le Contrôleur. Chacune correspond à une brique de votre application.

Le Modèle

Pour ménager le suspens, et surtout pour ne pas compliquer le propos, je n’aborderai pas le Modèle dans l’article d’aujourd’hui - ce sera le cas dans le prochain article que je lui consacrerai entièrement. Pour aujourd’hui tout ce que vous aurez besoin de savoir à son sujet est qu’il s’agit d’une couche d’ORM vous permettant d’interagir avec la base de données. Le nom de la gem qui s’occupe de cela pour Rails est ActiveRecord, et il s’agit d’une implémentation du Design Pattern du même nom.

Le Contrôleur

Le Contrôleur est la première zone importante que nous verrons aujourd’hui : il s’agit de la couche qui s’intercalle entre le Modèle et la Vue et qui fait surtout passer des objets de l’une à l’autre . Dans un sens, le Contrôleur va récupérer des objets venant du Contrôleur et les faire passer à la Vue. Dans l’autre sens, il va récupérer par exemple les informations provenant des formulaires que vous aurez créés dans la Vue pour peupler des objets de Modèle.

Si vous devez retenir quelque chose de tout cela, voyez le Contrôleur comme un Passeur .

La Vue

La Vue est généralement plus simple à aborder quand on débute, mais elle prend quelques temps pour être maîtrisée à son plein potentiel : en effet, de nombreux développeurs connaissent déjà l’utilisation de moteurs de template tels Smarty, Dwoo, etc. qui permettent d’optimiser les performances et surtout d’éviter que « ces *** de graphistes aillent fourrer leurs vilaines pattes dans mon beau code PHP » (c’est du presque vécu ;)).

Plus sérieusement, l’intérêt pour nous est avant tout de rendre le code plus facile à maintenir en évitant de mélanger la manipulation d’objets issus du Modèle et leur affichage à propremment parler .

C’est pourquoi on évitera au maximum de placer du code opérationnel dans la Vue (plus facile à dire qu’à faire en vrai, car les tentations sont nombreuses, mais c’est un objectif vers lequel il faut tendre) : les Assistants que nous verrons un peu plus tard vous aideront dans cette tâche.

L’autre avantage est de faciliter la réutilisation de code grâce aux Vues Partielles , ce sur quoi je reviendrais également un peu plus loin, dès que nous nous serons plongés dans la réalisation de votre première application ;).

... Une quatrième ?

Hééé oui : les développeurs se sont vite rendus compte que trois couches n’étaient pas suffisantes, et c’est pourquoi une quatrième (et dernière, je vous rassure) couche a vu le jour : ActiveResource. Elle n’est pas essentielle pour démarrer, (mais après c’est une drogue, vous verrez) et c’est pourquoi j’ai choisi de ne revenir vers elle que dans mon quatrième article dédié à Ruby on Rails.

Pour en résumer l’intérêt, c’est elle qui va assurer la communication entre les requêtes HTTP reçues par votre serveur et vos Contrôleurs, pour dire à ces derniers quelle action déclencher. Elle fait en somme l’association entre l’URL dans le navigateur et votre application. Cette couche est réglée pour fonctionner par défaut de la façon la plus intuitive qui soit, c’est pourquoi nous n’aurons pas besoin d’y toucher immédiatement.

Découvrons le générateur de code !

Assez de blabla ! Découvrons maintenant votre meilleur ami dans le monde du développement avec Ruby on Rails, la ligne de commande et le générateur de code. Il ne fait pas le travail à votre place (pas encore, hélas) mais créera pour vous les fichiers nécessaires pour commencer à travailler directement.

Nous découvrirons toutes les possibilités offertes par la génération de code au fur et à mesure des articles, mais aujourd’hui nous verrons uniquement la génération de Contrôleur, qui est fondamentale.

Création de la structure de l’application

La commande rails vous servira a démarrer une nouvelle application dans le répertoire de votre choix. Elle créera pour vous tous les fichiers nécessaires au bon démarrage de votre développement. C’est le premier générateur de code qu’on utilise, et c’est aussi le plus simple (rails --help vous indiquera toutes les options qu’il est possible de lui passer).

Comme vous pouvez le constater le nombre de répertoires à la racine du projet est relativement modeste, le nom de chacun parlant pour lui même. Voyons un peu ceux dont nous auront besoin aujourd’hui :

  • app/ : placez dans les répertoires views controllers et models vos différentes classes MVC. Nous les créerons en utilisant d’autres générateurs, mais rien ne vous empêche de les créer à la main.
  • public/ : c’est là que vous placerez vos images, vos javascripts ainsi que les feuilles de style. C’est en somme le répertoire fourre-tout de votre application.
  • script/ : vous utiliserez fréquemment les scripts placés dans ce répertoire, notamment generate et server, ainsi que console.

Vérifions maintenant que tout est en ordre. Pour cela placez-vous à la racine de votre projet et entrez la commande suivante :

Et voilà, votre application est démarrée : si vous pouvez voir l’écran habituel à l’adresse http://localhost:3000, c’est que tout va bien !

Création du premier contrôleur

Générons notre premier contrôleur dans un nouveau terminal en tapant par exemple :

Rails a donc créé notamment un fichier accueil_controlleur.rb dans le répertoire app/controllers. Ainsi que vous vous en doutez, c’est celui ci que nous allons éditer par la suite.

Tout d’abord, renommez le fichier index.html dans le répertoire public/ pour indiquer à Rails que vous ne voulez plus voir l’écran d’accueil.

Si vous vous rendez maintenant à l’adresse http://localhost:3000/accueil, vous devriez obtenir le message suivant : « Unknown action - No action responded to index. Actions : ». C’est tout à fait normal : en effet, vous n’avez encore renseigné aucune action dans le contrôleur que vous venez de créer. Rails ne peut encore rien faire pour vous ;) !

Ajout d’une action au contrôleur

Ajoutons donc une action à ce contrôleur : il s’agit d’une simple méthode Ruby placée dans la classe AccueilController placée dans le fichier app/controllers/accueil_controller.rb :

  1. class AccueilController < ApplicationController
  2.  
  3.   # Voilà le nouveau contenu de cette classe : comme vous le voyez,
  4.   # elle étend la classe ApplicationController. Cette classe est définie dans
  5.   # le fichier application.rb qui est voisin du fichier accueil_controller.rb :
  6.   # elle est particulièrement utile lorsque vous souhaitez faire partager des comportements
  7.   # des objets, etc. à vos Contrôleurs. Vous aurez tôt fait de lui trouver une occupation !
  8.  
  9.   # L'action index est toujours invoquée lorsqu'aucune action n'est spécifiée dans l'url
  10.   def index
  11.     # Je n'ai rien à faire, je passe la main.
  12.   end
  13.  
  14. end

Nous avons défini une fonction qui ... ne fait rien ! En effet, Rails ne nous oblige même pas à déclarer cette fonction si nous voulons passer la main à la Vue sans rien faire de spécial. En pratique, je vous conseille de la déclarer tout de même, c’est plus propre.

Si nous retournons sur http://localhost:3000/accueil, que va-t-il se passer d’après vous ? Eh non, ça ne va toujours pas fonctionner ! Nous n’avons pas encore défini de vue, et Rails nous le fait savoir : « Template is missing - Missing template accueil/index.erb in view path /home/pierre/rails/mon_blog/app/views : ».

Ce message est intéressant car il prouve que Rails a des conventions très claires qui nous permettent d’écrire moins de code : il s’attend à trouver un fichier "index.erb" dans le répertoire des vues qui concernent notre contrôleur, app/views/accueil/.

Créons la Vue qui manque !

PNG - 144.8 ko

Nous allons maintenant boucler la boucle en ajoutant la Vue pour notre action index. Créons donc le fichier app/views/accueil/index.html.erb. Le nom du fichier lui même correspond à une convention : html est le format que nous allons générer (on aurait pu créer du xml, un flux rss, etc.) et erb le moteur de template par défaut employé dans Rails.

  1.     <title>Page d'accueil de mon Blog</title>
  2.   </head>
  3.     <h1>Hello from Ruby on Rails !</h1>
  4.   </body>
  5. </html>

Ce coup-ci, un rechargement de la page donne enfin un résultat positif ! Nous affichons la page d’accueil de notre futur blog.

Communication Vue - Controlleur

PNG - 139.9 ko

Cet exemple était intéressant pour découvrir la démarche, mais nous ne faisons pour l’instant pas de choses très passionnantes avec Rails. Mettons le un peu à l’épreuve en testant ses capacités en calcul mental ! Nous allons lui demander d’effectuer un calcul dans le Contrôleur, de stocker le résultat dans une variable d’instance qui sera passée à la Vue, puis d’afficher le résultat dans la Vue.

Nous allons donc devoir revenir sur le code de notre contrôleur Accueil (app/controller/accueil_controller.rb) en modifiant la méthode index de la façon suivante :

  1. class AccueilController < ApplicationController
  2.   def index
  3.     # En Ruby, les variables d'instance sont signalées par le @ devant leur nom
  4.     # Dans Rails, elles nous servent à passer des données à la Vue.
  5.     @resultat_calcul = ( 2 + 3 ) * 4
  6.   end
  7. end

Reste maintenant à modifier la vue pour la rendre capable d’afficher le résultat de ce calcul :

  1.     <title>Page d'accueil de mon Blog</title>
  2.   </head>
  3.     <h1>Effectuons un calcul ...</h1>
  4.     <p>Le résultat est <%= @resultat_calcul %>
  5.   </body>
  6. </html>

Comme vous le constatez, nous avons affiché le résultat à l’aide d’une syntaxe qui s’apparente au raccourci qu’il est possible d’utiliser avec PHP (ou même ASP si je ne me trompe pas).

Et voilà le résultat, tel qu’il s’affiche dans le navigateur : « Le résultat est 20 ».

C’est tout pour cette semaine !

Le programme de départ était ambitieux, mais je préfère couper cet article en deux plutôt que de prendre une semaine de plus pour l’écrire. Nous verrons la semaine prochaine les choses que je n’ai pas traité aujourd’hui, à savoir :

  • Gestion de flux avec les Filtres.
  • Réutilisation de code grâce aux Vues Partielles, aux Assistants et aux Squelettes.
  • Utilisation des Flashs et de Content_for.
  • Cas concret : une authentification rudimentaire mais complète.

Il y a eu effectivement beaucoup de blabla dans cet article là, le prochain sera moins verbeux, c’est promis : il me semblait nécessaire de bien expliquer afin de bien poser les bases du fonctionnement de Rails, et c’est pourquoi j’ai fait le choix de favoriser la théorie dans cet article ... Nous serons plus pratiques la semaine prochaine : comme toujours avec Rails, le meilleur est à venir ;) ! Voir l’article suivant ...

Dandelionmood.com a déménagé !

Votez pour cet article sur

Vos réactions

Killian, le 18 février 2009
Je trouve l’architecture des projets assez intelligente, pour l’instant je ne suis pas déçu et je trouve même qu’il est plus simple de démarrer comparé à un projet Django. Par contre, j’ai du installer le gem sqlite3 (gem install sqlite3-ruby), car j’avais droit à une belle erreur :) Bon tuto !
Pierre Quillery, le 18 février 2009

Oups, effectivement j’ai oublié de préciser qu’il fallait installer cette gem (j’avoue que je me fais avoir à chaque fois que je réinstalle mon PC avec celle-là ^^’). Je corrige le tuto en conséquence ...

Sinon je cherche un bon moyen de faire des screencasts avec Ubuntu et pour l’instant ... Je cherche encore ! Si quelqu’un connaît un bon soft, je suis toutes ouïes ;) ...

Etan, le 19 février 2009

Pour les screencasts, tu peux essayer gtk-recordmydesktop, ça fonctionne assez bien.

Le .deb est dispo ici : http://www.getdeb.net/app/RecordMyDesktop

L’archive tar.gz se trouve là : http://sourceforge.net/project/showfiles.php ?group_id=172357

Pierre Quillery, le 19 février 2009
Merci pour le lien Ethan :) ... Cependant, je n’ai trouvé que de vieilles versions de ce projet sur getdeb (hardy), le mieux était encore de compiler tout ça (ce qui n’était pas bien dur ;))...
Raphaël, le 23 février 2009

Qu’appelles tu "assistants" ?

Si ce sont les helpers, pourquoi ne pas garder leurs noms initiaux ? Certes c’est en anglais mais un débutant qui cherchera de la doc ou de l’aide trouvera plus facilement son bonheur sous ce terme...

Pierre Quillery, le 23 février 2009

@Raphaël : oui, ce sont bien les Helpers auxquels je fais référence en parlant d’Assistants. Tu as tout à fait raison, sur le principe, et je clarifie le terme dans l’article suivant où je parle plus longuement de leur rôle.

Je parle plus volontiers moi-même de "Helpers" que d’Assistants, mais il me semble qu’à l’écrit le minimum qu’on puisse faire est au moins d’éviter de jargonner en mélangeant Français et Anglais sans cesse. Après je sais bien que c’est un choix qui présente des inconvénients, malheureusement.

Comme dit, je précise le terme Anglais dans l’article suivant et je fournis un lien vers la documentation officielle, je suppose que ce sera suffisant pour lever le doute ;) ...

wenzib, le 5 avril 2009
Très bonne introduction c’est exactement le type d’article que je recherchais. Tu devrait peut être préciser qu’il faut faire un rake db:create pour créer la base de donnée et éviter de se retrouver avec une erreur.

Laissez un message !

Qui êtes-vous ?

Un message, un commentaire ?