Ruby on Rake, ou comment Rake m'a rendu alcoolique
Je n’ai pas pour habitude de traduire les textes d’autrui, je ferai une exception pour cette fois sans rien y ajouter ni retrancher. D’abord parce que je ne vois pas ce que je pourrais dire de plus, ensuite parce que l’esprit même du texte rentre pour une bonne partie dans son intérêt, enfin parce que Rails manque trop de bonnes documentations en français, et que celle ci vaut le déplacement.
Ceci est la traduction de Ruby on Rails rake tutorial, de Greg Pollack.
Si vous développez en Ruby on Rail, vous avez certainement utilisé l’utilitaire Rake afin de lancer les tests, ou pour mettre à jour votre base de données en lançant rake db:migrate. Mais avez-vous vraiment conscience de ce qui se passe lorsque vous lancez une tâche Rake ? Savez-vous qu’il vous est possible de créer vos propres tâches rake, ou même de créer votre propre librairies de ces si pratiques descripteurs de tâches ?
Voici quelques cas d’usages des tâches Rake :
- Récupérer une liste d’inscrits afin d’envoyer un email.
- Lancer des traitements de calcul et de statistiques pendant la nuit.
- Supprimer et régénérer le cache d’une application.
- Sauvegarder ma base de données et mon dépôt subversion.
- Exécuter n’importe quel traitement de données.
- Me saouler la gueule.
Dans ce billet, vous allez découvrir le pourquoi de l’existence de Rake, et comment il peut vous aider dans le développement de vos applications Rails. À la fin de cette lecture, vous devriez être capable de créer vos propres tâches et de finir bourré comme un coing grâce à Rake en seulement trois petites étapes.
Pourquoi faire un retour en arrière ?
Pour comprendre les origines de Rake, il convient de s’intéresser un peu à son vénérable ancêtre, j’ai nommé Make.
Je vous propose un voyage dans le temps, à l’époque où le code devait obligatoirement être compilé, c’est à dire avant que l’iPhone et les langages interprétés ne parcourent la planète.
À cette époque, quand vous téléchargiez un logiciel, vous obteniez généralement des fichiers contenant le code source et un script shell. Ce script contenait tout ce que votre machine avait besoin de savoir afin de compiler, lier et construire votre application. Vous lanciez install_me.sh, chacune des lignes du fichier était exécutée, et vous obteniez au bout d’un moment un exécutable.
Ça marchait plutôt pas mal, il faut l’avouer, à part peut être pour les quelques développeurs de l’application. Chaque fois qu’ils changeaient la moindre ligne de code, il leur fallait relancer le script afin de tout recompiler. cela prenait évidemment un temps fou pour les gros logiciels.
En 1977, Stuart Feldman des laboratoires Bell inventa Make, qui résolut la majorité des problèmes liés aux compilations à répétition. Make est également utilisé afin de compiler des programmes, mais avec deux différences majeures :
- Make est capable de reconnaître quels fichiers ont été modifiés depuis la dernière compilation. Il pouvait donc ne compiler que ce qui avait changé d’une fois sur l’autre. Autant dire que cela a dramatiquement réduit les temps de compilation.
- Make peut aussi résoudre les dépendances. Il sait que pour être compilé, le fichier A a besoin du fichier B, qui lui-même a besoin de fichier C. Ce qui fait que si Make tente de compiler le fichier source A et que le fichier source B n’a pas été compilé, il commence par traiter ce dernier.
Je ne devrais pas continuer sans vous expliquer que Make est un simple exécutable, un peu comme “ls”, ou “dir”, et qu’il a besoin pour fonctionner d’un fichier annexe, appelé un “makefile”, qui va contenir toutes les sources et les dépendances du programme à compiler. Les “makefiles” ont leur propre syntaxe cabalistique qu’il ne nous sera pas donné de voir ici.
Au fur et à mesure, Make a évolué, et on a commencé à l’utiliser pour d’autres langages. En fait, de nombreux développeurs Ruby l’utilisaient avant l’avènement de Rake.
“Mais, Ruby n’a pas besoin d’être compilé, alors à quoi ça sert ?”. Vous ne l’avez peut-être pas dit, mais vous l’avez certainement pensé très fort.
Oui, je suis d’accord, Ruby est un langage interprété, et nous ne compilons pas notre code. Alors pourquoi utiliser Make ?
Eh bien, pour au moins deux raisons fondamentales :
- Automatiser des tâches : toute application d’envergure se termine presque fatalement par l’écriture de scripts à lancer en ligne de commande, qu’il s’agisse de lancer une maintenance, supprimer un cache ou faire évoluer la base de données. Et au lieu de créer une dizaine de petits scripts shell, ou un gros, vous pouvez aussi créer un seul “Makefile” dans lequel vous organiserez les choses à faire en tâches. Vous pouvez ensuite exécuter les tâches en lançant “make stupid”, c’est à dire littéralement “fait l’imbécile”, et cela lance la tâche “stupid”.
- Vérifier la résolution des dépendances entre les tâches. Quand vous lancez des opérations de maintenance en chaîne, vous en répétez fatalement certaines d’une tâche à l’autre. Par exemple, migrer une base de données et en faire une extraction ont toutes deux une connexion à la base pour prérequis. Vous pouvez donc créer une tâche de connexion qui sera lancée juste avant la migration.
Et Rake, dans tout ça ?
Il y a quelques années, Jim Weirich utilisait régulièrement Make sur un projet en Java. Tout en travaillant sur son Makefile, il réalisa combien il lui serait pratique d’avoir des bouts de Ruby dedans. Et Rake était né.
Jim donna à Rake la possibilité de réaliser des tâches, résoudre les dépendances, et même éviter de recommencer des tâches qui avaient déjà été réalisées. C’est évidemment quelque-chose que nous ne faisons pas vraiment, puisque Ruby n’est pas un langage compilé.
Comment ça marche ?
Imaginons que je veuille me saouler la gueule, quelles en seraient les étapes ?
- J’irais acheter à boire.
- Je me servirais à boire.
- Je boirais jusqu’à plus soif.
Si je voulais utiliser Rake pour chacune de ces tâches, je créerais un fichier nommé Rakefile, qui contiendrait quelque-chose comme ça :
Je peux maintenant lancer ces tâches depuis le répertoire où se trouve mon Rakefile, comme ça :
Sympa non ? Malheureusement, je ne vérifie pas que les tâches sont effectuées dans le bon ordre. Et bien qu’il puisse m’arriver de souhaiter être bourré avant d’avoir commencé à boire, ou même avant d’avoir acheté quoi que ce soit, ce n’est évidemment pas possible.
Rake et les dépendances
Maintenant, il me faut acheter à boire et me servir un verre avant de pouvoir me saouler la gueule convenablement. Cela donne donc :
Comme vous pouvez le voir, avant que je ne puisse boire, il me faut acheter de l’alcool et me servir un verre. L’ordre des choses est rétabli.
Avec le temps, vous risquez d’être tenté d’accroître votre alcoolisme, et donc votre Rakefile. Vous serez aussi certainement tentés de m’inviter à boire un coup. Comme dans tout logiciel d’envergure, rien ne vaut une bonne documentation.
Comment documenter mes tâches ?
Rake possède une manière très simple de documenter les tâches. Il s’agit de “desc” et c’est simple comme bonjour :
Comme vous pouvez le voir, chacune de mes tâches a maintenant une description. Mes amis peuvent les lire en tapant rake -T, ou rake --tasks.
Facile non ?
L’espace de nommage de Rake
Maintenant que vous êtes devenu un bon alcoolique, vous utilisez un grand nombre de tâches Rake, et vous avez besoin d’un bon moyen de les classer. C’est là que viennent les espaces de nommage. Si je devais utiliser un espace de nommage dans l’exemple précédent, il deviendrait :
Vous n’avez plus qu’à classer vos tâches en fonction des catégories, et OUI, vous pouvez en avoir plusieurs dans un même fichier. Maintenant, rake --tasks me donne :
Tu ne pourrais pas être un peu sérieux pour une fois ?
Les applications Rails viennent avec un lot de tâches prédéfinies, dont vous pouvez obtenir la liste en allant dans le répertoire de travail et en lançant rake --tasks. Si vous n’avez pas encore essayé, allez y, je peux attendre deux minutes…
Afin de créer une nouvelle tâche rake pour votre application Rails, vous devez dans un premier temps vous rendre dans le répertoire /lib/tasks (créé par défaut). Si vous y placez vos Rakefiles avec le suffixe “.rake”, celles-ci seront automatiquement récupérées par Rake. Nous allons ajouter la tâche suivante à notre application Rails.
Remarquez comment j’ai pu utiliser #{RAILS_ROOT} pour obtenir le chemin complet de l’application. Maintenant, si je lance rake --tasks dans le répertoire de mon application, je trouverai les nouvelles fonctions mélangées aux autres tâches Rake.
Génial ! Maintenant voyons comment ça devient vraiment utile.
Et on peux accéder aux modèles Rails depuis une tâche ?
Évidemment ! En fait, c’est même pour ça que j’utilise Rake : écrire des tâches que je lance à la main ou que je planifie en utilisant Crontab. Comme je le disais au début de l’article, j’utilise Rake pour les tâches suivantes :
- Récupérer une liste d’inscrits afin d’envoyer un email.
- Lancer des traitements de calcul et de statistiques pendant la nuit.
- Supprimer et régénérer le cache d’une application.
- Sauvegarder ma base de données et mon dépôt subversion.
- Exécuter n’importe quel traitement de données.
- Me saouler la gueule.
Sacrément utile, et facile qui plus est. Le code suivant récupère la liste des utilisateurs dont l’abonnement arrive à expiration et leur envoie un courriel :
Comme vous pouvez le voir, nous accédons au modèle en deux étapes : la directive require et le => :environment.
- require File.expand_path(File.dirname(__FILE__) + “/../../config/environment”)
- task(:send_expire_soon_emails => :environment) do
Pour lancer ça tous les soirs à minuit, je n’ai qu’à créer une tâche dans Crontab, de cette manière :
Où trouver plus d’exemples ?
Maintenant que vous en savez assez pour écrire des tâches utiles, je me suis dit que je pourrais vous laisser repartir avec quelques ressources supplémentaires. La meilleure manière de vous améliorer est encore de lire le code des autres, comme ces tâches Rake :
- Ces nouvelles tâches incluses dans Rails Edge remettent votre base de données à zéro pour vous.
- Craig Ambrose a écrit une tâche pour sauvegarder votre base de données.
- Adam Greene a écrit une série de tâches qui vous permettent de sauvegarder vos données sur Amazon S3.
C’est fait. Si vous en connaissez d’autres, n’hésitez pas à les publier dans les commentaires.
Toujours là ? Ça tombe bien, les gens de RailsEnvy à qui nous devons cet excellent article cherchent de nouveaux collaborateurs. Contactez Greg at RailsEnvy si ça vous intéresse.

Des menus déroulants à choix multiples sans select
On se retrouve tous un jour ou l’autre confronté au problème de questions à réponses multiples et encore plus nombreuses, sans possibilités de filtrage préalable. Dans ce cas, la première solution qui vient à l’esprit est celle du menu déroulant à choix multiple, et elle peut sembler alléchante à plus d’un point de vue.
Grave erreur ! Il n’y a pas pire pour votre utilisateur que cette extension de notre bon vieux select, dont j’avais sérieusement remis la fiabilité en question il n’y a pas si longtemps que cela. Je me suis rendu compte à mes dépends que les menus déroulants à choix multiples étaient aux formulaires ce que le blink et les gifs animés étaient aux pages web des années 90 : une plaie.
On fait tous des conneries, et moi le premier. Confronté à des formulaires dans lesquels je rencontrais de nombreux champs à réponse multiple sans aucun contrôle de ma part sur leur nombre, j’ai mis du menu déroulant partout, persuadé de détenir la bonne méthode. Horreur, malheur, dirait la sorcière si elle était là, le truc s’avère épouvantable à utiliser.
- Un clic de souris à coté, et on perd toute sa sélection.
- La sélection de cases non adjacentes relève du défi olympique.
- Difficile à styler, on s’y perd facilement entre les réponses.
J’ai cherché un moment avant de trouver une solution satisfaisante vues les contraintes qui m’étaient imposées :
- Un nombre infini de réponses potentielles.
- Accessibilité totale, donc pas de javascript.
- Facilement personnalisable.
La solution
Pas besoin de chercher bien loin. Remonter à l’origine du problème et aux avantages apparents de la solution choisie devaient me permettre de prendre la bonne direction.
Dans un formulaire, la première chose à laquelle on pense quand il s’agit de réponses multiples, c’est “cases à cocher”. Malheureusement, celles-ci deviennent rapidement impossible à afficher au delà de quelques éléments. D’où l’utilisation du menu déroulant à choix multiple, dont l’ascenseur permet d’occuper un minimum de place, mais au détriment de l’utilisabilité.
Il me fallait donc combiner les avantages des cases à cocher et des menus déroulants à choix multiples, sans sacrifier à l’accessibilité :
- Espace à l’écran restreint.
- Réponses multiples.
- Nombre de réponses indéfini et potentiellement infini.
Pour cela, je commence par englober mes réponses dans une div dont je force la hauteur et à laquelle j’attribue la propriété CSS overflow-y : auto. Voilà pour la partie déroulante.
J’ajoute ensuite une série de label dans lesquels j’englobe ma case à cocher. Si je trouve ça sémantiquement moyen – le label désigne le champ de formulaire, ce dernier ne saurait donc y être inclus – c’est structurellement valide. J’applique ensuite à chacun de mes labels la propriété CSS display: block
Ce dernier point est très important. En effet, si l’id de la case à cocher et la propriété for= du label sont renseignées correctement, la sélection du champ quand je clique sur le label s’étend à toute la ligne. Pratique non ?
Il ne me reste qu’à mettre un peu de couleur une ligne sur deux pour bien différencier les réponses, et le tour est joué. Évidemment, le résultat présenté est tout sauf joli, mais je vous rappelle que mon sens artistique avoisine le zéro absolu.
Télécharger le code source de l’exemple.
Les standards du web expliqués à ma mère
Les standards du web expliqués à ma mère
Ma mère utilise un ordinateur sous Windows Millenium “le seul avec lequel je n’ai jamais eu de problèmes”, appelle une unité centrale un “moteur” car ça fait du bruit et c’est ce qui fait propulse la machine, et a depuis longtemps oublié sa propre adresse courriel peu peu qu’elle l’ait jamais connu. Le jour où elle m’a demandé de lui expliquer ce qu’étaient ces fameux standards du web dont je parlais si régulièrement et qui avaient l’air tellement importants, je savais que la partie était tout sauf gagnée.
– Ces standards du web, c’est quoi ?
– Eh bien, c’est un code de bonne conduite pour créer des sites web qui ont la même apparence sous tous les navigateurs du marché.
– Ah, parce qu’il y a plusieurs navigateurs ? Je ne connais qu’Internet Explorer.
– Oui, il y en a tout un tas : Firefox, Netscape, Flock, Opéra…
– Et ça sert à quoi d’en avoir autant, ce ne serait pas plus simple de n’en avoir qu’un seul ?
– Hmmm… peut-être, si. Au fait, pourquoi roulez-vous dans une Clio verte ?
– Eh bien parce que c’est une bonne voiture, et qu’elle me plaît bien.
– Ce ne serait pas plus simple que tout le monde roule en Golf diesel bleue ? Plus de problèmes de pièces détachées, un seul type d’essence à la pompe… le bonheur quoi.
– Et laisser à une entreprise allemande le monopole de l’automobile en France ?
– Ben voilà, vous avez compris.
– Quel est le navigateur le plus utilisé ?
– Internet Explorer, avec 90% de parts de marché (la conversation est assez ancienne, ndlr).
– Et Internet Explorer suit ce code de bonne conduite ?
– Non, pas vraiment. En fait il ne suit que ce qu’il veut.
– Alors pourquoi parler de “standards”, s’ils ne sont pas suivis pas 90% des utilisateurs ?
– C’est que les standards du web n’ont pas valeur normative.
– On ne peut donc pas parler de norme. Dans ce cas, à quoi servent-ils ?
– Vous connaissez les normes ISO ? La norme ISO9002 par exemple.
– Oui, prend ta vieille mère pour une imbécile, je ne te dirai rien.
– L’institut ISO part d’une implémentation pour définir une norme. Le W3C définit des codes de bonne conduite à priori pour que les navigateurs puissent s’y conformer dans le futur.
– Le W3C ?
– Oui, une organisation indépendante composée de grands noms de l’industrie informatique. Elle élabore les préconisations que l’on appelle les standards du web.
– Et qui les rédige ?
– Des groupes de travail. L’activité du W3C va bien au delà de l’unification du rendu des pages web.
– Et Microsoft en fait partie ?
– Oui.
– Donc, si j’ai bien compris, les standards du web sont directives à valeur non normatives créées par des sociétés qui ne les appliquent pas dans leur propre produit, produit qui se trouve de fait être le navigateur standard sur le web. C’est bien ça ?
– En quelque sorte, oui…
– Eh beh, nous voilà biens…
Note : cette conversation a été à peine déformée, dans un soucis de concision et de clarification.

Hi, I'm Ruby on Rails! (2)
Après Java, c’est au tour de PHP de subir l’humour ravageur de Gregg et Jason, dans une autre parodie des publicités Apple. Et c’est bon !
Je trouve juste dommage qu’ils tournent sous Mephisto quand Typo leur tend les bras…
Hi, I'm Ruby on Rails !
Histoire de bien terminer la journée, je vous propose de découvrir cet amusant détournement des fameuses publicités Hi, I’m a PC / Hi I’m a Mac de la firme à la pomme sur les avantages comparés de Ruby on Rails et du champion toutes catégories des usines à gaz inutilisables, j’ai nommé Java. C’est drôle, fin, et tout à fait vrai.
Développer une galerie web en rails, avec slideshow, resize des images, vignettes et RSS en 20 minutes, en mangeant un plat de sushis
On n’est jamais mieux servi que par soi-même, dit le proverbe. Aussi, afin de remplacer Photostack vraiment trop limité et brouillon ai-je décidé de développer ma propre galerie d’images, mais vite (et bien), car je n’ai pas vraiment que ça à faire.
En termes de fonctionnalités, je compte partir sur des bases simples, que j’améliorerai au fur et à mesure.
- De multiples galeries.
- La prise en charge du redimensionnement des images.
- La création automatique de vignettes.
- Un slideshow qui permette aux visiteurs de faire défiler l’ensemble d’une galerie sans aucun effort.
- Un flux XML pour du RSS ou de l’atom.
Pour le côté technique, j’ai dit vite – le temps d’avaler un plat de sushi – et propre. Cela exclue donc forcément PHP, au profit de Ruby on Rails. Maintenant, on fait comme dans la chanson, on monte sur les tables, on lève les bras bien haut, allez c’est parti !
Création de l’application
Nous commençons par créer une nouvelle application Rails.
Et pour fêter ça, j’attrape un premier sushi à l’oursin. Miam !
Ajout des galeries
Nous créons maintenant tout ce dont nous avons besoin ajouter, parcourir, modifier et supprimer des galeries.
Notre galerie possédera les attributs suivants :
- Un titre.
- Une description.
- Un état (en ligne / hors ligne).
- Une position.
Nous avons utilisé les fonctionnalités de génération automatique de Rails. Elles nous permettent maintenant de disposer de :
- Le formulaire de création et de modification de notre galerie /galleries/new.
- L’affichage HTML (sommaire) de notre galerie: /galleries/1.
- Un flux XML, for fun and profit : /galleries/1.xml
Aurais-je omis de dire que l’application est RESTful ? Oui ? Comme c’est dommage. Je vais donc noyer mon chagrin dans un second sushi, au saumon cette fois.
Ajout des images
Il nous manque le plus important : l’ajout et la visualisation des images. Comme précédemment, nous allons laisser Rails travailler pour nous et générer tout ce dont nous avons besoin, ou presque.
Nos images auront pour attribut :
- Une galerie parente. Nous créerons le menu déroulant plus tard.
- Un nom de fichier.
- Une vignette.
- Un sushi aux oeufs de saumon.
- Un poids en ko.
- Une hauteur en pixels.
- Une largeur en pixels.
- Une position.
- Un titre.
- Une description.
- Un état (en ligne / hors ligne).
Gestion de l’upload et du redimensionnement
Pourquoi faire compliqué et réinventer la roue quand on peut faire simple et laisser les autres travailler pour soi ? Je vous propose donc d’installer le greffon attachment_fu, et de manger un sushi à l’anguille fumée avant qu’il ne soit complètement froid.
C’est fait, il ne nous reste plus qu’à lier les briques ensemble.
Dans app/model/gallery.rb
Nous spécifions la relation entre les galeries et les images : à une galerie correspond plusieurs images.
Et ligne 18 :
Il s’agit du champ correspondant à l’image que notre greffon s’attend à recevoir. Ne le décevons pas.
Dans app/model/picture.rb
Nous appelons notre greffon avec toutes les informations dont il a besoin :
- Nous stockons nos images sur le disque local. Nous pourrions aussi le stocker sur le service S3 d’Amazone de manière totalement transparente.
- L’image fera maximum 500 ko.
- Elle sera redimensionnée en 600*450 pixels.
- La vignette fera 120*90 pixels.
Dans app/views/pictures/new.rhtml ligne 5
Tout ça m’a donné faim. Et vous ?
Dans app/vews/galleries/show.rhtml
L’affichage plein écran et le slideshow
Une fois de plus, pas question de réinventer la roue quand d’autres le font pour moi. Nous nous en allons donc faire un tour du côté de chez Xuan et télécharger Splash Image, un script clica convi qui remplace avantageusement Lightbox sans nécessité 2go de RAM. Et pourquoi ne pas manger un sushi au thon tant qu’on y est ?
wget http://www.chez-xuxu.net/ressources/javascript/splash.image/splash.image.zip
Nous décompressons l’archive dans public/javascripts, et faisons les inclusions qui vont bien.
Dans app/views/layout/galleries.rhtml
Dans app/vews/galleries/show.rhtml
Nous remplaçons la ligne précédemment ajoutée par celle-ci :
Elle nous permet de grouper les images de cette galerie et de les faire défiler en pleine fenêtre comme si de rien n’était.
Conclusion
Voilà, c’est fini, ou presque. Il ne me reste plus qu’à ouvrir mon plat de maki et à nettoyer tout ça. Certes, ce n’est pas bien joli, mais ça marche. Je vais faire un peu de nettoyage dans le code, rajouter une feuille de style correcte, et mettre les sources sur un subversion afin que vous puissiez récupérer tout ça. Merci beaucoup à Bastien pour m’avoir montré le plugin upload_fu et avoir supporté mes blagues vaseuses toute la journée.
Vendredi, nous ajouterons une authentification basique, l’upload de masse depuis un système de fichier ou un ftp, les jolies URL search engine friendly et les tags le temps de nous siffler une ou deux pintes de Guiness que vous aurez eu la gentillesse de m’offrir par SMS comme il se doit.
[Edit] J’ai mis une démonstration du résultat final en ligne. Elle est accessible sur 20 minutes gallery et la démonstration est totalement fonctionnelle.

Passer d'une application single user à une application multi users
Vous avez développé une petite application pour vos propres besoins, par exemple un outil de publication en ligne. Des gens l’ont remarquée et ont commencé à s’y intéresser, au point que vous la publiiez sous une licence quelconque, pour le plus grand bien de la communauté. Et un jour, ce qui allait très bien pour une seule personne ne suffit plus, et vous décidez de franchir le pas : rendre votre application multi utilisateurs. Belle initiative, mais par où commencer ?
Quels utilisateurs ?
Commencez par remettre à plat l’ensemble des fonctionnalités de votre outil. Recensez chacune d’entre elles et classez les par groupe en fonction des utilisateurs “type” qui seront amenés à les utiliser.
Dans notre cas, nous séparons les fonctionnalités de l’application en 3 groupes distincts :
L’administration
- La configuration.
- Le paramètrage du thème.
- La sélection des greffons.
- La gestion des utilisateurs.
La publication
- La gestion / publication des billets.
- La gestion des catégories.
- La gestion des média.
- La modération des commentaires.
La contribution
- Ajout de commentaires.
Et voilà, nous avons défini 3 profils types, et défini leurs attributions possibles. Nous aurions pu en définir plus, par exemple un rédacteur qui aurait des droits d’écriture mais pas de publication, ou un modérateur pour les contributions qui n’aurait pas de droits en écriture, mais nous choisissons la simplicité. Reste maintenant à l’implémenter dans notre application, et là, deux choix s’offrent à nous.
Implémentation par profils
L’implémentation par profils est la plus simple à mettre en oeuvre, au détriment de la souplesse. On attribue un profil à chaque utilisateur, puis, pour chacune des actions possibles, on contrôle le profil de l’utilisateur, et on agit en conséquence. Pour cela, on va créer 3 méthodes, vérifiant que l’utilisateur dispose bien du profil voulu :
Vous remarquerez que pour chaque profil inférieur, on vérifie également que l’utilisateur dispose du profil supérieur. En effet, on considère que les utilisateurs hiérarchiquement les plus élevés disposent de fait des droits les plus bas.
Implémentation par droits
Beaucoup plus complexe à mettre en place, l’implémentation par droit est en revanche extraordinairement souple. Elle ne convient cependant pas à n’importe quelle application car elle a son petit effet “usine à gaz”, vous pèserez donc bien le pour et le contre avant de la mettre en place.
Le principe est simple : vous définissez une série de droits ; chacun de ces droits correspond à une action possible sur l’application : créer une catégorie, modifier un billet, effacer un commentaire, afficher la liste des utilisateurs… Vous remarquerez au passage que ce système de droits repose sur le CRUD (Create, Read, Update, Delete) et trouve tout à fait sa place dans une application RESTful, mais je m’égare. Une fois définis les droits, vous créez les profils fonctionnels que nous avons vus tout à l’heure, et vous leur attribuez les droits qui vont bien. L’administrateur les aura à priori tous, le contributeur n’en aura que très peu. Pour cela, faites un tableau de correspondance entre les deux. Il y a d’ailleurs de fortes chances pour que vous ayez le même dans votre application :
| Droits | Administrateur | Rédacteur | Contributeur |
|---|---|---|---|
| Créer un billet | X | X | |
| Ajouter un utilisateur | X | ||
| Ajouter un commentaire | X | X | X |
Vous assignez ensuite un profil à chaque utilisateur. Pour chaque action possible, vous vérifierez que l’utilisateur dispose bien du droit adéquat. Pour cela, on va créer une méthode toute simple :
Deux choses rendent cette implémentation par droits formidablement souple :
- Vous pouvez ajouter autant de profils que vous le souhaitez, puisque ceux-ci ne sont que des conteneurs à doits. Les droits sont en effet liés à l’utilisateur et le profil ne sert qu’à les grouper.
- Vous pouvez très facilement surcharger un profil en attribuant ou supprimant des droits à un utilisateur spécifique.
Et maintenant ?
Il ne vous reste plus qu’à vous mettre au travail, en réfléchissant bien à ce que vous souhaitez faire de votre application. Chaque système a ses avantages et ses inconvénients, et passer de l’un à l’autre est tout sauf évident.

Et pour ceux qui pensent que ce billet est une réflexion sur ce que pourrait devenir Typo dans un futur proche, vous vous trompez. 50% du code est déjà fait, il me reste à le propager à l’ensemble de l’application.
Le Google developpers day passera à Paris
Le 31 mai prochain, Google organise une journée d’ateliers et de conférences autour de ses nombreuses API à destination des développeurs du monde entier. L’étape française se déroulera à Paris, dans un lieu tenu secret, de 13 à 21 heures. Cette journée représente une excellente opportunité de rencontrer les ingénieurs qui réalisent ces applications que nous utilisons au quotidien et pour vous familiariser avec l’énorme potentiel de ces outils.
Une API est un protocole permettant à une application de communiquer avec une application tierce. Les API ont joué un très grand rôle dans l’essor du web 2.0, créant notamment la vague des mashups, des applications utilisant de nombreuses API pour un résultat parfois étonnant.
Je m’y rendrai certainement, car je suis particulièrement motivé par les API Google Mobile, Google Map, et Google Aps.
Les inscriptions sont gratuites, et les premiers arrivés seront les premiers servis.

Quel CMS ou framework utiliser pour faire un site de rencontres ?
Parcourir ses statistiques de fréquentation à la recherche des mots-clé amenant le visiteur sur votre site est toujours intéressant. Ces derniers fourmillent souvent de surprises amusantes, mais ils vous permettent surtout de vérifier l’adéquation des résultats de recherche avec le contenu publié. Parmi les phrases revenant régulièrement, cms ou framework pour faire un site de rencontre m’a donné envie d’offrir un semblant de réponse aux pauvre âmes en peine rentrées bredouilles après un passage sur ce blog. La question étant relativement large, et ne fixant notamment pas de limitations technologiques, il m’a semblé pertinent de définir le besoin fonctionnel d’un tel site afin de proposer l’option technique la plus performante.
Inscription des utilisateurs
Le système utilisé doit permettre l’inscription libre des utilisateurs. Idéalement, celle-ci doit permettre le choix de son profil minimal :
- Sexe : masculin / féminin.
- Type du compte : gratuit / payant.
- Âge.
- Cible recherchée (âge et sexe).
On pourra choisir de créer des règles spécifiques en fonction du type de compte choisi et du sexe de la personne, selon les modèles éprouvés du genre :
- Gratuit pour les filles.
- Compte gratuit aux fonctionnalités limitées.
- Compte gratuit, complet, mais limité dans le temps.
- …
Cela impliquera donc un système d’inscriptions particulièrement souple avec un workflow et la gestion du paiement en ligne, ce qui n’existe pas à ma connaissance sur les CMS du marché. L’utilisation d’un framework sera donc recommandée dans ce cas précis, à moins de souhaiter modifier en profondeur le gestionnaire d’inscription du CMS. Une étude de rentabilité des deux solutions serait intéressante.
Gestion des profils et droits
L’application devra proposer une solution de gestion de profils et de droits, que l’on opte pour des profils utilisateurs multiples ou pour un profil unifié. Un site de rencontre nécessite en effet des fonctionnalités avancées d’animation et de modération afin de pallier aux problèmes régulièrement rencontrés sur des services de genre : prostitution, harcèlement…
En ce qui concerne la fiche des utilisateurs, qui sera visible par l’ensemble des inscrits sur le site, il faudra à un moment ou un autre trancher entre deux solutions :
- La fiche et le profil des utilisateurs ne sont qu’une seule et même chose, certaines informations étant publiques et d’autres privées.
- La fiche de l’utilisateur est une composition à part entière, complètement indépendante du profil de l’utilisateur, minimaliste.
La seconde solution me semble la plus intéressante. Certains des éléments du profil pourront en effet servir de fiche temporaire le temps que la fiche des utilisateurs soit validée par les modérateurs de la plate-forme, et pourront de plus être affichés en “fiche minimale” pour les comptes gratuits ou les visiteurs, par essence pas encore enregistrés : vous voulez en savoir plus ? Eh bien payez maintenant.
En ce qui concerne la fiche elle-même, elle devra comporter un très grand nombre de champs, précis, et si possible remplis par des menus déroulants, afin de simplifier au maximum les contraintes techniques des fonctions de recherche.
Workflow de publication de la fiche
Je me suis interrogé un instant sur le bien fondé de l’utilisation d’un CMS pour un site de rencontres. Cette solution m’avait semblé un peu curieuse jusqu’au moment où je me suis rappelé que la majorité des sites du genre modéraient les fiches des utilisateurs à priori. On peut dès lors considérer cela comme un workflow de publication avec plusieurs profils :
- Les visiteurs, qui peuvent visualiser une partie des fiches.
- Les membres, qui peuvent visualiser l’ensemble des fiches.
- Les rédacteurs (qui sont aussi les membres), qui rédigent leur propre fiche, mais sans les droits de publication.
- Les responsables de publication, qui ont le droit de modération à priori sur les fiches des membres.
Se pose alors la complexité des profils utilisateurs des sites de rencontres, généralement très fournis, et peu compatible avec les fonctionnalités de publication de base d’un CMS. Les fonctionnalités de workflow rendent néanmoins ces derniers intéressant.
Recherche interne
Le site doit proposer deux types de recherche :
- Une recherche simple, basée sur le profil.
- Une recherche avancée, basée sur la fiche descriptive.
La recherche simple devra principalement porter sur trois critères :
- Qui ? (âge, sexe…).
- Quoi ? (relation durable ou éphémère)
- Où ? (localisation géographique).
La recherche avancée devra refléter la fiche descriptive des utilisateurs autant que faire se peut, afin de sortir des fiches les plus pertinentes possibles. L’utilisation d’un thesaurus dans le moteur de recherche sera un plus particulièrement appréciable.
Messagerie interne
Qui dit rencontre dit contact, donc messagerie interne, au moins dans un premier temps.
Celle-ci devra être particulièrement simple d’utilisation, tout en proposant un minimum de fonctionnalités :
- Classement par thread.
- Insertion du texte dans les réponses.
- Ajout de pièces jointes.
L’utilisation de cette messagerie ne devra pas être le but du site en soi, les utilisateurs étant évidemment invités à (commu)niquer de manière plus directe le plus rapidement possible.
Alors, CMS ou framework ?
Comme diraient les humoristes Chevalier et Laspales, c’est vous qui voyez. Certains CMS comme Joomla proposent par défaut un bon nombre des fonctionnalités citées dans ce billet, mais des développements lourds seront nécessaire. L’avantage d’un framework dans ce cas résiderait dans les fonctionnalités existantes pour conduire un développement spécifique, comme celles offertes par Ruby on Rails et ses nombreux greffons (comme Authorization pour les gestion des utilisateurs). Seule une estimation des temps de développements en fonction du périmètre fonctionnel recherché permettra de trancher.

Rails, ou pourquoi faire compliqué quand on peut faire simple ?
Je découvre avec émerveillement l’attribut :include d’ActiveRecord::Base, qui efface de mon esprit des années de cauchemars SQL.
Jugez plutôt, quand une horreur pareille
devient tout simplement :
C’est beau, pour un peu j’en pleurerais.

Billets précédents :

Passionné d'informatique depuis l'âge de six ans, je travaille en tant que responsable qualité chez blueKiwi Software, éditeur spécialiste des outils collaboratifs en entreprise. Ma double formation en sciences politiques et en informatique me permet de porter un regard particulier sur les problématiques abordées par mon poste.