Ruby on Rails Valid XHTML 1.1Cette page est conforme à la norme CSS!Mise à jour 08-2014
SOMMAIRE

Présentation
    Description
    Arborescence
    Utilisation
Les exemples
Les outils et liens
Télécharger les exemples
PRESENTATIONRetour en haut de page


Description Suiv.

La description qui suit est succinte et ne couvre pas toutes les subtilités et possibilités de Rails (entre autres les procédures de test). Elle permet néanmoins d'en comprendre le fonctionnement et d'éclairer un peu l'aspect parfois "magique" de ce framework. En bas de page, des liens orientent vers des sites plus complets, avec des explications très détaillées sur les mécanismes de Rails.

D'autre part, une application de bibliothèque est fournie et commentée. Elle illustre l'utilisation du framework par des exemples concrets.
L'étude des exemples des tutoriels est un bon préalable à l'apprentissage de ce logiciel, même si leur simplicité et leur utilisation standard du framework masquent un certain nombre de choses automatiques.


Rails est donc un framework de développement Web.

Il obéit au modèle de programmation MVC : Modèle - Vue - Contrôleur.
Ces trois éléments ont des attributions particulières bien séparées, ce qui clarifie la conception et l'écriture des applications.

Le modèle
Le modèle définit les tables de la base de données et les relations entre elles. Il est indépendant des bases utilisées. C'est lui qui permettra, grâce à l'ActiveRecord, les lectures des tables et des automatismes comme la recherche automatique d'enregistrement liés, et aussi les différentes opérations de mise à jour (ajout, modification, suppression). On y définit aussi des contrôles automatiques sur les champs des tables, qui seront automatiquement exécutés lors de la mise à jour de la base. Si la mise à jour échoue, les erreurs éventuelles créeront des messages appropriés qu'il sera possible de récupérer pour les afficher.

Exemple de liens, dans une bibliothèque un auteur a écrit des livres. Quand les liens sont correctement définis, on peut accéder aux livres de cet auteur juste en lisant la table des auteurs, sans autre code d'accès.

La vue
La vue est le composant qui définit la présentation des données fournies par le modèle.
On y trouve du code html pur et aussi du code spécifique qui utilise des helpers standard pour générer du code html (formulaire, bouton, champ en lien avec la base, ...).

Le contrôleur
Il reçoit des requêtes sous forme d'url, soit directement tapées dans le navigateur, soit par des demandes issues de la vue (lien ou bouton).
En fonction de l'url, il exécute une action, constituée de code écrit en Ruby. La transaction peut contenir des données, qui seront utilisés pour déclencher des requêtes (lecture, écriture) vers le modèle et orienter les données vers la prochaine vue appropriée.

Il faut ajouter à ces composants le mécanisme de routage qui lie une url à une action d'un contrôleur.

le fonctionnement peut donc se résumer ainsi :
  • le serveur rails reçoit une url
  • le routage transforme cette url en action d'un contrôleur
  • cette dernière interroge/met à jour la base de données via le modèle
  • le contrôleur envoie les données à la vue qui envoie le flux html au navigateur
  • le navigateur, via les différentes actions possibles (liens, boutons) renvoie une url au serveur rails

Rails travaille autour de trois principes :
  • DRY (Don't Repeat Yourself) : réutiliser aussi souvent que possible le code existant. C'est l'utilisation des layouts et des helpers.
  • REST : design pattern, organisé autour de verbes HTTP standard (GET, POST, PUT, DELETE)
  • Convention over configuration. Beaucoup de choses n'ont pas besoin d'être exprimées; Rails adopte automatiquement des comportements par défaut.
    Il faut avouer que ceci est un peu déroutant parce qu'il se passe des choses "dans le dos", ce qui correspond à l'aspect "magique" évoqué au début.
    Par exemple, si une vue porte le même nom que l'action du contrôleur, celui-ci n'a pas à explicitement demander l'affichage de la vue. Il est évident que cette façon de procéder est chaudement recommandée.

Arborescence et types de fichiers Préc.Suiv.

L'arborescence d'un projet rails est un peu complexe. Chaque répertoire et sous-répertoire contient des fichiers dont la fonction est bien définie : les vues ne sont pas mélangées avec les contrôleurs ...
Je ne cite ici que les plus courants que l'on doit renseigner.
Le premier porte le nom de l'application. Il contient de nombreux répertoires et fichiers qui composent un environnement complet de développement et d'exécution. Seuls sont décrits ci-dessous ceux qui constituent l'application.

app
Contient les principaux composants de l'application, dans l'ordre alphabétique :
  • assets/stylesheets : les feuilles de style (.css et .scss)
  • controllers : les contrôleurs (.rb), par exemple, un pour gérer les auteurs, un autre pour les livres
  • helpers : du code ruby (xxxxxxx_helper.rb) qui peut figurer au niveau de l'application (xxxxxxx = "application") ou au niveau d'un contrôleur (xxxxxxx=nom du contrôleur)
    Ce code peut être appelé dans une action ou dans une vue
    Il existe aussi des helpers intégrés à Rails, que l'on utilise de la même façon.
  • models : définit les modèles (.rb) des tables, au niveau de leurs relations et des contrôles d'intégrité, ... Les structures sont définies ailleurs
  • views/xxxxxxx : définit par contrôleur (xxxxxx) les différentes vues utilisées (.html.erb)
  • views/layouts : des morceaux de code (.html.erb, identique à celui des vues) à intégrer dans les vues. Par exemple, le haut de page, pour ne pas le répéter dans chaque vue (principe DRY)

config
Fichiers de configuration de l'application.
  • routes.rb : définition des routes (lien contrôleur-action avec url)
db
Contient les bases de données des différents environnements (développement, test) selon leur nature (sqlite par défaut, mysql, ...) et leur description.
  • developpment.sqlite3 : base de données du mode développement
  • schema.rb : description des tables et de leurs champs, ainsi que les contrôles à effectuer sur ces champs
  • migrate : ce dossier contient les scripts de migration -modification des structures des tables- successifs (fichiers .rb). Un script de migration peut être inversé pour ôter l'effet de son application. Le principe "convention over configuration" transforme automatiquement une création de table en suppression ... Le fichier schema.rb est automatiquement mis à jour.
Beaucoup d'autres répertoires et fichiers existent, mais il n'est pas obligatoire de modifier leur contenu. Voir dans les tutoriels plus de détails et explications sur ceux-ci.

Utilisation Préc.

Rails propose plusieurs outils pour parvenir à nos fins.

Création de l'application
La première étape est de créer l'arborescence de l'application.
Se positionner dans le répertoire dédié aux applications rails et taper la commande rails new biblio. On dispose maintenant dans le répertoire biblio de l'arborescence définie précédemment.
Se positionner dans ce répertoire.

Création de la base de données
Par défaut, Rails propose de travailler avec sqlite. Il n'est alors pas utile de modifier la configuration. C'est le choix adopté.
Pour créer la définition de la table des auteurs, taper la commande rails generate model auteur autabr:string{10} autnom:string{30}.
Celle-ci génère deux fichiers : le modèle app/models/auteur.rb et le fichier de migration db/migrate/aaaammjjHHMMSS_create_auteurs.rb Puis lancer la commande rake db:migrate pour créer la table dans la base. Si elle échoue, il peut être nécessaire de la lancer comme suit : bundle exec rake db:migrate
A ce stade, Rails a déjà mis en oeuvre des automatismes :
  • ajout du champ id, qui représente la clé primaire de la table
  • ajout du champ created_at, pour la date/heure de création de la ligne
  • ajout du champ updated_at, pour la date/heure de modification de la ligne
  • le nom du modèle prend une majuscule (Auteur)
  • le nom de la table créée est auteurs (pas de majuscule, pluriel)
Procéder de même pour la table des livres. Il est bien sûr possible de faire d'abord tous les generate model puis de lancer ensuite le rake db:migrate.

Il est possible de supprimer ces automatismes au prix de quelques manipulations un peu délicates.
L'avantage de conserver le standard est que les définitions des tables sont plus simples, lorsque l'on veut définir les associations entre elles.
En effet, dans le modèle Auteur, on dit simplement has_many :"livres". Dans le modèle Livre, on indique belongs_to :auteur. Noter le pluriel et le singulier.
Ceci suppose que dans la table des livres on ait défini un champ auteur_id qui représente la clé étrangère de l'auteur.
Il est possible d'utiliser des noms différents pour les ids, les relations sont un peu plus difficiles à définir (il faut intervenir manuellement dans les fichiers modèles et dans les fichiers de migration).

Utilisation de la base
Dans le répertoire de l'application, lancer la console par rails console --sandbox (sandbox indique que les données seront perdues en fermant la session).

a=Auteur.new crée une instance vide du modèle Auteur
Réponse : # < Auteur id: nil, autabr: nil, autnom: nil, created_at: nil, updated_at: nil >

On voit donc une instance vide, dont il faut renseigner les valeurs, sauf celles qui sont automatiques.
a.autabr="ABR"
a.autnom="Nom"
a.save
a
Réponse : # < Auteur id: 15, autabr: "ABR", autnom: "Nom", created_at: "2014-08-17 12:17:23", updated_at: "2014-08-17 12:17:23" >

b=Auteur.create(:autabr => "ABR 2", :autnom => "Nom du 2"). Cette commande est équivalente à new ... save.

Pour retrouver les auteurs, taper Auteur.find(:all). Pour obtenir le n° 15, taper Auteur.find(15)
Pour modifier cette ligne :
a=Auteur.find(15) puis a.autnom="Nom 1" et enfin a.save.

Procéder de la même façon pour créer des livres, en n'oubliant pas d'affecter au champ auteur_id l'id d'un des auteurs créés.
Ensuite, en recherchant un auteur ( a=Auteur.find(15) ), on peut lister ses livres avec a.livres.

Find propose d'autres critères de sélection (par nom de champ, critères multiples ...). Voir la documentation complète pour plus de détails.

Création d'un contrôleur
Lancer la commande rails generate controller ctl action1 action2 Ceci crée plusieurs éléments :
  • un contrôleur nommé ctl, doté des actions action1 et action2
  • deux vues action1 et action2
  • les routages pour ces deux actions dans routes.rb
Lancement de l'application
Démarrer le serveur rails par rails server
Dans le navigateur, taper localhost:3000/ctl/action1

Création d'un scaffold
Un scaffold est un ensemble qui permet en une seule étape de générer une application de mise à jour d'une table (contrôleur, vues, modèle, routage).
La syntaxe est rails generate scaffold Table zone1 puis rake db:migrate pour créer la table. Le modèle s'appelle Table, le contrôleur tables et les vues sont dans le répertoire tables. Elles ont le même nom que les actions du contrôleur.
Le code de l'application est minimal, avec beaucoup de comportements par défaut.
Evidemment, la présentation générée n'est pas très ergonomique, mais donne une base de développement qui fonctionne.

Un scaffold ne peut gérer qu'une table et ne peut donc servir à des applications trop complexes.


LES EXEMPLES DETAILLESRetour en haut de page


Présentation de l'exemple Suiv.

L'exemple proposé ici est une classique application de bibliothèque.
Il est organisé autour de 3 tables : des auteurs, des catégories et des livres. Un livre appartient à un auteur et est défini par sa catégorie.

L'écran est structuré également de manière classique, avec un bandeau horizontal pour le titre, un bandeau vertical à gauche pour le menu et une partie centrale recevant les différents formulaires. Eux-mêmes sont organisés toujours de manière identique : un titre, un corps et un pied de page regroupant les boutons d'action.

Il existe deux types de formulaires :
  • liste : chaque ligne de la table sur une ligne de l'écran, avec au bout les liens pour modifier la ligne ou la supprimer
  • saisie/modification : une ligne de la table est affichée, les champs les uns sous les autres
Sur les écrans de saisie de données, un message d'erreur au bas de l'écran indique la première erreur rencontrée lors de la validation. Le message n'est pas sur une page séparée, qui obligerait à revenir en arrière pour corriger.

Exemples de pages :
liste des auteurs ajout d'un auteur

Contraintes techniques Préc.Suiv.

Afin de bien appréhender le fonctionnement de rails, en ne bénéficiant pas des automatismes qu'il propose, j'ai choisi de m'écarter du standard sur plusieurs points :
  • les noms d'action ne sont pas standard
  • les noms de route sont personnalisés
  • les id des tables ne sont pas nommés "id"
  • les id des clés étrangères ne sont pas nommés "table_id"
J'ai en revanche utilisé au maximum des helpers pour des fonctions générales et des layouts pour la présentation des vues.

Les fichiers de l'application Préc.Suiv.

Ce chapitre liste les fichiers de l'application avec une explication succinte de leur conception et de leur contenu.
De plus amples informations figurent à l'intérieur.

La base de données
Les structures sont créées par les fichiers du répertoire db/migrate.
Dans l'ordre des noms, on crée les auteurs, puis les livres, en respectant les standard de nommage des champs.
Ensuite, on crée les catégories, avec des noms de champs personnalisés, puis on met à jour la description des livres en ajoutant une nouvelle clé étrangère.

Dans le répertoire app/models se trouvent les modèles des tables dans lesquels on décrit les clés primaires et les associations entre tables. On constate, lorsqu'on utilise des noms de champs standard, que certaines définitions sont automatiques; si on s'éloigne de ce standard, il faut tout spécifier.

Noter également l'utilisation du singulier et du pluriel dans la dénomination des tables, des modèles, des associations. S'en écarter nécessite des paramètres supplémentaires.

Les routes
Les routes sont contenues dans le fichier routes.rb du répertoire config.
Différentes syntaxes équivalentes permettent de donner à des url (controleur/action) des noms plus parlants et qui masquent les noms techniques.

Ainsi la ligne match "valider_ajout_dun_auteur" => "auteurs#ajoutvalid", :via => :post renvoie sur l'action ajoutvalid du contrôleur auteurs, avec le verbe html POST, qui envoie les données du formulaire.
Au lieu de donner le nom technique de l'url, le programme l'invoque en l'appelant valider_ajout_dun_auteur_path.

A contrario, la ligne get "auteurs/ajout",sans renommage, est disponible via la variable automatique auteurs_ajout_path.

Les feuilles de style
Les feuilles de style sont contenues dans le répertoire app/assets/stylesheets.
Une feuille de nom application.css fournit des informations de compilation pour les autres feuilles d'extension .scss. Par défaut, toutes les feuilles scss, quel que soit leur nom, sont automatiquement prises en compte.
On en constitue une par contrôleur pour des raisons de commodité, mais on pourrait tout mettre directement dans la feuille application.css., ou trouver toute autre organisation.

Les layouts
Les layouts, qui sont des gabarits pour les vues, sont dans le répertoire app/views/layouts. Il sont utilisés pour toutes les vues, qui ne doivent plus fournir que leurs spécificités qui s'intègrent par une commande "yield" dans le gabarit.
On peut aussi créer des "partials" qui sont des morceaux de code des vues, et que l'on peut insérer dans n'importe quelle vue par la commande "render", sans avoir à recopier tout le code commun.
On trouve donc :
  • _part_entete_html.erb : c'est un "partial", qui définit le début de la page
  • _part_pied_html.erb : c'est un "partial", qui définit le bas de la page
  • application.html.erb : c'est le layout par défaut qui s'applique à toutes les vues (sans le mentionner), le menu de l'application (bandeau de gauche) sur la plupart des pages. Il inclut les deux "partials"
  • administrateur.html.erb : c'est le layout spécifique attaché au lien "auteurs" du menu. La vue qui réalise la liste des auteurs est affichée en spécifiant ce layout

Les helpers
Les helpers sont des modules qui définissent des fonctions que l'on peut glisser dans une vue ou un contrôleur.
L'application possède un helper, chaque contrôleur aussi.

Le fichier app/helpers/application_helper.rb contient une fonction qui retourne le titre de la page, en fonction du contrôleur et de la dernière action exécutée. Ainsi, le code est minimal dans chaque vue et centralisé dans un seul fichier, plus facilement exploitable et maintenable.
Les helpers auteurs, categories et livres contiennent une fonction qui a pour but d'orienter le formulaire vers l'action suivante; par exemple quand on est sur la page d'ajout d'un auteur, la validation du formulaire doit le diriger vers l'action de validation des données.
Comme la vue appelée modif est commune à l'action d'ajout et à celle de modification; il faut indiquer dans le formulaire quelle url doit être utilisée lors de sa validation.
Ceci est nécessaire car le principe REST n'a pas été adopté, il faut donc faire le travail soi-même.

Cette fonction calcul_action qui porte le même nom dans chaque contrôleur aurait pu aussi bien être écrite dans application_helper.rb, comme pour le titre des écrans.

Les vues
Les vues sont rangées dans le répertoire app/views, un sous-répertoire par contrôleur.

Elles décrivent seulement les spécificités d'une action, la partie commune aux pages étant gérée par un layout.
Pour le contrôleur livres, on trouve trois vues au comportement différent.

La vue liste
Elle se compose d'une boucle qui balaie une liste des livres, établie par le contrôleur, et génère le code html ligne à ligne.

La vue modification
Elle est utilisée pour l'ajout et la modification.
Elle crée un formulaire via le helper intégré form_for. On lui associe une instance de la table que l'on veut gérer, instance créée dans le contrôleur avant d'afficher la vue. Ensuite, par des helpers text_field, on établit le lien entre le champ à l'écran et le champ de la table.
Pour les livres, on veut aussi afficher une liste déroulante de choix des auteurs. On utilise alors le helper fields_for qui accède à une instance de la table auteurs.
La liste déroulante est définie par le helper select.

La vue recherche
Là aussi un formulaire est créé, mais il n'est pas attaché à une table. C'est le helper form_tag qui est utilisé, au lieu de form_for.
Les champs qu'il s'agit de mettre à jour sont des cookies qui serviront dans la liste des livres à opérer des sélections au niveau du contrôleur.

On utilise dans toutes les vues d'autres helpers, comme link_to pour définir des liens.

Les contrôleurs
Les contrôleurs sont dans le répertoire app/controllers.

Ils comportent en général les actions suivantes :
  • Liste : crée la liste des lignes à afficher et active la vue du même nom
  • Ajout : crée une instance vierge de la table puis active la vue modif
  • Ajoutvalid : activée par la validation du formulaire, lance le contrôle des données, retourne sur la vue modif si erreur, sinon met à jour la ligne et réaffiche la liste
  • Modif : crée une instance de la table avec l'enregistrement choisi dans la liste, puis active la vue modif
  • Modifvalid : activée par la validation du formulaire, lance le contrôle des données, retourne sur la vue modif si erreur, sinon met à jour la ligne et réaffiche la liste
  • Supprvalid : supprime la ligne puis retourne à la liste. La confirmation est demandée par la vue
  • Controle : effectue la vérification des données entrées; retourne 1 si une anomalie est rencontrée, 0 sinon.
    Beaucoup de contrôles peuvent être effectués par la base (champ obligatoire, longueur maximum, unicité, ...). Il suffit alors de tester la bonne exécution de l'écriture de la ligne pour détecter la survenue d'une erreur. Ce n'est pas mon choix dans cet exemple.

Le déboggage Préc.

Rails propose un outil de déboggage que je n'ai pas encore testé.
Le principal souci rencontré pendant la mise au point des programmes concerne la structure des paramètres passés entre les vues.
La solution que j'utilise est de se servir du champ d'erreur placé dans chaque vue pour afficher le contenu du tableau associatif params reçu par l'action, d'afficher la vue par un render, puis de sortir de l'action. C'est assez rudimentaire mais permet de visualiser ce tableau et de comprendre les imbrications qu'il comporte.

LES OUTILS ET LIENSRetour en haut de page

Interpréteurs

Disponible gratuitement en téléchargement sur le site railsinstaller.org.
Il fournit une version de Ruby et une version de Rails. Il est préférable pour éviter tout problème d'installation de prendre la package complet.


Liens

Ces sites proposent des cours et documentations sur le framework.

Ruby on rails tutorial, par Michael HARTL
developpez.com, initiation
Codelearn
RailsGuides