Le blog de la CT2C

Starter App - Partie 2 - Des Gems pour le développement !

Par Régis Millet aka Kulgar , publié le 16 Décembre 2016

Vers la partie précédenteVers la partie suivante
Actualisé le 16 Décembre 2016 pour une Starter App fonctionnant en Ruby 2.2 et Rails 4.2

Dans cette deuxième partie, nous allons découvrir et intégrer trois gems facilitant certaines tâches de la phase de développement. Nous allons évidemment continuer avec notre StarterApp dans l'état final de la précédente partie et à chaque fois je vous expliquerai comment mettre en place la gem, comment l'utiliser, son rôle, etc.


Nous allons voir les gems suivantes :
  • - magic_encoding
  • - quiet_assets
  • - annotate

Ce sont trois gems que j'utilise énormément et que nous allons voir un peu plus en détail. C'est parti !


Magic Encoding


Dépôt GitHub

Je commence par celle-ci car elle ne nécessite aucune configuration et n'est même pas à intégrer dans votre Gemfile. Installez-la en ligne de commande comme ceci :

$ gem install magic_encoding

L'utilisation et l'utilité de cette gem sont toutes simples. Nous allons un peu suivre le principe du TDD et commencer par écrire une ligne de code qui va faire naître un bug dans notre application puis résoudre ce bug à l'aide de la gem. Ouvrez le fichier app/controllers/client_pages_controller.rb et modifiez l'action home comme ceci :

def home
flash.now[:notice] = "Problème d'encodage"
respond_to do |format|
format.html { render :home }
end
end

Lancez-votre serveur et rendez-vous sur la page d'accueil : http://localhost:3000. Et là, nous avons un beau We're sorry but something went wrong due à une erreur HTTP de code 500 pour signaler une erreur interne au serveur. Si nous regardons les logs du serveur, nous voyons :

SyntaxError [...]/client_pages_controller.rb:4: invalid multibyte char (US-ASCII)

Cela pointe justement notre ligne contenant un accent è. Cette erreur survient parce que par défaut, toutes les chaînes de caractères Ruby sont encodées en ASCII-8BIT (ou US-ASCII, ou encore encodage binaire) et cet encodage ne contient pas d'équivalent pour tous les caractères spéciaux (lettres avec accents, cédilles, etc.). Il nous faut donc préciser un encodage différent et une des solutions est d'utiliser un commentaire dit "magique" ressemblant à : # encoding: UTF-8. Oui, mais il faudrait le faire pour tous les fichiers .rb ! Et c'est là que la gem magic_encoding entre en jeu. Dans un terminal, à la racine de votre projet, exécutez la commande :

$ magic_encoding
"Magic comments set for 22 source files"

Cette simple commande ajoute cette ligne de code :

# -*- encoding : utf-8 -*-

Dans tous vos fichiers.rb ! Après ça, vous n'avez qu'à rafraîchir votre page d'accueil pour la voir s'afficher correctement.
Espérons que dans la prochaine version de Ruby (2.0) ils aient songé à changer d'encodage par défaut...

Notez qu'avec magic_encoding vous pouvez préciser n'importe quel encodage en l'ajoutant en tant qu'option à la commande. A chaque fois que vous exécuterez la commande, cela remplacera les commentaires "magiques" déjà présents par le nouvel encodage spécifié.

Attention ! Le commentaire magique doit rester la première ligne de votre fichier.rb autrement il ne sera tout bonnement pas pris en compte !

Si vous souhaitez en savoir plus sur tous les problèmes d'encodage dans Ruby On Rails, je vous invite à lire notre autre article sur les encodages en ROR.


Profitons-en pour terminer toutes les configurations nécessaires pour un bon encodage homogène en UTF-8 dans toute l'application de Ruby On Rails. (J'inscris ici un résumé de l'article pointé ci-dessus).

# Dans le fichier config/application.rb, ajoutez-y la ligne (s'il elle n'y est pas déjà, ce qui devrait être le cas pour toute application Ruby > version 1.9) : 
config.encoding = "utf-8"

<!-- Dans le Head de votre application, ajoutez-y la balise méta suivante : -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

# Dans le fichier config/environment.rb modifiez-le comme ceci (et pas différemment) 
# -*- encoding : utf-8 -*-
# Load the rails application
require File.expand_path('../application', __FILE__)

# Set default encodings for datas that come in and out the application
Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8

# Initialize the rails application
StarterApp::Application.initialize!

Et c'est à peu près tout pour l'encodage et magic_encoding. Vous aurez à utiliser la commande magic_encoding chaque fois que vous créerez des nouveaux fichier.rb contenant des caractères spéciaux.

Quiet Assets


Dépôt GitHub

Cette gem est toute simple : elle éradique purement et simplement les logs concernant vos assets. Oui car une chose que je trouve particulièrement inutile, c'est la multiplication des lignes comme celles-ci dans les journaux de développement du serveur Web :

Started GET "/assets/application.css?body=1" for 127.0.0.1 at 2013-01-18 14:53:50 +0100
Served asset /application.css - 200 OK (2ms)

Je trouve que ces lignes noient les informations réellement utiles. Quiet assets permet simplement de bloquer l'enregistrement des informations concernant les assets dans les journaux, laissant ainsi uniquement les informations apportant un plus pour le développement et le test de son application. Ils préconisent de n'ajouter cette gem que pour l'environnement de développement. Soit ! C'est tout à fait normal car en production et en test nous voudrons tout de même connaître les éventuelles erreurs sur les Assets. Ajoutons donc cette gem dans notre Gemfile :

group :development do
gem "quiet_assets", ">= 1.0.1" # https://github.com/evrone/quiet_assets
end

Et c'est tout ! Il n'y a rien d'autre à faire. Faites un bundle install, relancez votre serveur, rafraîchissez votre page et vous ne verrez plus les logs concernant les Assets. Désormais lors du rafraîchissement, je n'ai plus que :

Started GET "/" for 127.0.0.1 at 2013-01-18 15:10:36 +0100
Connecting to database specified by database.yml
Processing by ClientPagesController#home as HTML
Rendered client_pages/home.html.erb within layouts/application (30.4ms)
Completed 200 OK in 56ms (Views: 55.5ms | ActiveRecord: 0.0ms)

Si jamais vous souhaitez remettre temporairement les journaux concernant les Assets (notamment ça peut être utile si vous utilisez Paperclip), inscrivez cette ligne dans config/environments/development.rb :

config.quiet_assets = false

Gem simple à mettre en place, mais bien utile pour faciliter l'exploration de vos Logs à la recherche d'erreurs.

Création de Models avant de continuer


Ah ! Voilà une autre de mes gems préférées. Pour celle-ci, nous allons devoir créer un model pour pouvoir la tester. Nous en profitons pour créer plusieurs models pour qu'in fine les pages publiques de notre site soient entièrement dynamiques. Allons-y, dans un terminal, lancez la commande :

$ rails generate model ClientPage title:string webtitle:string webdescription:text name:string published:boolean home:boolean 

Nous créons un nouveau model ClientPage qui stockera les pages publiques de notre site Web. Pour ces pages, nous fournirons :
  • - Un titre title, qui sera placé dans une balise <h1> en haut de la page
  • - Un titre webtitle, qui sera placé dans la balise <title> de la page Web
  • - Une description webdescription qui sera placée dans la balise <meta description> de la page
  • - Un nom name qui nous servira de référence pour la page
  • - Et deux booléens published et home pour indiquer si la page sera publiée publiquement et pour la définir en tant que page d'accueil du site ou non

Modifions la migration comme ceci :

class CreateClientPages < ActiveRecord::Migration
def change
create_table :client_pages do |t|
# nous ajoutons quelques options par défaut
t.string :title, :null => false
t.string :webtitle, :null => false
t.text :webdescription
t.string :name, :null => false
t.boolean :published, :default => false
t.boolean :home, :default => false

t.timestamps
end
end
end

Pour faire les liens vers ces pages, nous aurons également besoin d'un menu en associant un bouton à chaque page. Nous allons donc créer un autre model :

$ rails generate model ClientMenuButton priority:integer name:string page_id:integer

Nous leur fournirons un nom, une "priorité" pour les ordonner plus facilement et leur associerons une page donc nous ajoutons la colonne page_id. Idem, nous allons modifier le fichier migration :

class CreateClientMenuButtons < ActiveRecord::Migration
def change
create_table :client_menu_buttons do |t|
t.integer :priority, :null => false, :default => 1
t.string :name, :null => false
t.integer :page_id

t.timestamps
end
end
end

Enfin, pour que le contenu des pages soit dynamique, créons un dernier model (mais n'effectuez pas la migration ! ) :

$ rails generate model ClientPageContent title:string priority:integer body:text page_id:integer css_class:string

Nous fournirons à ces contenus :
  • - Un titre, qui sera placé dans une balise <h2>
  • - Une priorité, pour ordonner ces contenus plus facilement
  • - Un corps, qui contiendra le contenu proprement dit
  • - Une (ou plusieurs) class CSS, pour personnaliser leur apparence, au besoin

Et nous allons également modifier le fichier de migration :

class CreateClientPageContents < ActiveRecord::Migration
def change
create_table :client_page_contents do |t|
t.string :title, :null => false
t.integer :priority, :null => false, :default => 1
t.text :body, :null => false
t.integer :page_id, :null => false
t.string :css_class

t.timestamps
end
end
end

Avec tout ça, nous sommes parés pour mettre en place et tester les deux dernières gems : Annotate et Bullet.

Gem Annotate


Dépôt GitHub

La gem Annotate permet d'annoter certains fichiers automatiquement. Par exemple, pour les models, elle va automatiquement détecter les colonnes créées dans la table associée au model et ajouter des informations utiles, en commentaires, dans le fichier du model. Bon... La pratique vaut mieux que tout beau discours !

Commençons par ajouter la gem à notre Gemfile :

group :development do
gem "quiet_assets", ">= 1.0.1" # https://github.com/evrone/quiet_assets
gem "annotate", :git => 'git://github.com/ctran/annotate_models.git' # https://github.com/ctran/annotate_models
end

Faites ensuite les commandes suivantes :
$ bundle install
$ rails g annotate:install

Cela va vous générer un fichier dans lib/tasks qui devrait automatiser le lancement de la commande annotate chaque fois que vous ferez une migration. Modifiez légèrement ce fichier, comme ceci :

Annotate.set_defaults({
'position_in_routes' => "after",
'position_in_class' => "after",
'position_in_test' => "after",
'position_in_fixture' => "after",
'position_in_factory' => "after",
# [...]

J'ai simplement modifié les positions de façon à ce que les annotations viennent en fin de fichier plutôt qu'en début. A présent, effectuons enfin la migration des models que nous avons créé.

$ rake db:migrate

A la date où j'écris cet article, l'annotation automatique n'est pas encore fonctionnelle, mais ce n'est pas grave, elle viendra.


La migration se déroule sans pépins (en principe ) et nous pouvons enchaîner sur la précieuse commande :

$ annotate
Annotated (3): ClientPageContent, ClientPage, ClientMenuButton

Commande qui vous annonce qu'elle a annoté trois fichiers. Allez donc voir l'un d'entre eux, par exemple ClientPage et vous verrez qu'en fin de fichier s'est ajouté :

# == Schema Information
#
# Table name: client_pages
#
# id :integer not null, primary key
# title :string(255) not null
# webtitle :string(255) not null
# webdescription :text
# name :string(255) not null
# published :boolean default(FALSE)
# home :boolean default(FALSE)
# created_at :datetime not null
# updated_at :datetime not null
#

Et c'est ce que j'aime dans cette gem . Elle nous résume les différentes colonnes de la table en un commentaire concis et clair. Je trouve cela pratique car au fil du développement on perd très vite quelles colonnes ont été créées et quels attributs nous pouvons modifier et utiliser. Utilisez-la après les migrations, et elle annotera automatiquement les models associés à vos tables.

Elle peut également annoter le fichier routes.rb avec les routes obtenues par la commande rake routes, mais personnellement je préfère avoir ces routes dans un fichier externe en utilisant la commande : $ rake routes > routes.txt.

Notez que la modification des positions dans le fichier de configuration .rake était importante pour notre cas. En effet, si nous laissons before et qu'un commentaire magique d'encodage généré par magic_encoding est déjà présent, annotate va ajouter les annotations avant ce commentaire. Dès lors, il ne sera plus pris en compte. D'ailleurs, n'oubliez pas de lancer un petit magic_encoding pour vos fichiers model.rb fraîchement créés.

Il y a pas mal d'autres options pour cette gem, je vous laisse les découvrir sur le dépôt de GitHub.


Et ce sera tout pour cette partie. Nous avons vu trois petites gems très utiles (en tout cas, je les utilise beaucoup) et très simples d'intégration. Dans la prochaine partie, nous découvrirons Faker et la gem Bullet. La première permet de créer facilement un bon nombre de données avec très peu d'efforts, idéal pour tester son application avec des données aléatoires ou non. La deuxième gem vise à nous aider à optimiser notre application en nous signalant les requêtes superflues ou des requêtes de type N+1. Je vous donne rendez-vous la semaine prochaine pour les découvrir !


Index -- --

  • Aucun commentaire - Soyez le premier !

Insérez votre commentaire
  1. Min: 50 caractères, Max: 800. Actuellement: 0 caractères

  2. ne pas remplir