Ruby on Rails par Grafikart – quelques astuces

En regardant en diagonale quelques vidéos de Grafikart sur Ruby on Rails, j’ai noté quelques astuces intéressantes :

rails s -b IP

Pour binder l’IP sur laquelle l’application écoute.

Par exemple, rails s -b 0.0.0.0 permet d’écouter sur toutes les interfaces (utile pour les machines virtuelles)

Callback de modèle

Pour ne pas avoir à ajouter du code dans le contrôleur (après un @objet.save par exemple).

Son exemple était l’utilisation d’un before_validation pour setter le slug en fonction du titre d’un article.

Scope avec paramètre

exemple :

scope :online, -> (online) { where(online: online) }

Scope par défaut

default_scope where(published: true)

Attention aux effets de bord, notamment si on met un order dans le defaut_scope et qu’on veut redéfinir le tri dans le contrôleur !

Pour éviter ces effets de bord, les méthode reorder, unscoped et unscope peuvent être intéressante.

render mon_objet

Si on a un partial du même nom qu’une classe, on peut directement utiliser cette syntaxe.

Exemple : si on boucle sur un tableau d’élément pour les afficher les uns sous les autres, on peut écrire :

@elements.each do |element|
  render element
end

à partir du moment où on a un fichier partial _element.html.erb.

On peut même écrire :

render "element", collection: @elements

ou même :

render @elements

qui donnera le même résultat. Et ça c’est fort !

content_for et yield

Penser à les utiliser !

content_for(:title, @element.titre)
 
yield(:title)
 
content_for?(:title)

exemple :

content_for?(:title) ? yield(:title) : "Mon super titre"

config.generators

On peut configurer les fichiers qui sont générés quand on fait un rails ... dans le application.rb. Par exemple, pour ne pas créer un helper à chaque fois qu’on génère un contrôleur, on peut écrire :

config.generators.helper = false

Plus d’infos sur guides.rubyonrails.org.

Lancer un serveur en production

rails s -e production

Attention, il faut du coup une base de données de production.

Supprimer un contrôleur et les fichiers associés

Quand on crée un contrôleur avec la commande rails g controller mon_controleur, plusieurs fichiers sont générés : le contrôleur, le fichier de test, un fichier SCSS et un fichier JS (ou Coffee).

Pour supprimer ce contrôleur et tous les fichiers associés, on peut utiliser la commande :

rails d controller mon_controleur

Utiliser un CDN

config.action_controller.asset_host = 'cdn.domain.fr'

Preview d’email

Quand on génère un mailer avec rails g mailer mon_mailer, il est généré un fichier mailer dans /app/mailers, un répertoire de vues dans app/views, mais aussi un fichier de preview dans test/mailers/preview.

Dans ce fichier, on crée des méthodes qui appellent celles du fichier mailer. Par exemple, si notre fichier mailer contient un méthode contact(prenom), on peut définir une méthode contact dans notre fichier preview :

ContactMailer.contact("Toto")

Ensuite, on peut accéder au preview via l’url rails/mailers/contact_mailer qui liste toutes les méthodes de preview.

Associations

.includes

Exemple : on affiche un tableau d’articles avec pour chaque article sa catégorie. Pour cela, dans le contrôleur on aurait écrit :

@articles = Article.all

Et dans la vue, quelque chose comme :

<%= article.categorie.titre %>

Cela n’est pourtant pas très efficace : on a une requête qui récupère les articles :

SELECT * FROM articles

et pour chaque article, une requête qui va chercher sa catégorie :

SELECT * FROM categorie WHERE id = 2 LIMIT 1

Soit n+1 requêtes (où n correspond aux nombres d’articles).

Pour contrer cela, on peut faire dans le contrôleur :

@articles = Article.includes(:categorie).all

Ce qui donnera, au niveau des requêtes :

SELECT * FROM articles
SELECT * FROM categories WHERE id IN (2,3)

On peut même faire :

@articles = Categorie.includes(articles: :tags).all

Pour récupérer toutes les catégories et les articles associés ainsi que les tags associés aux articles.

:dependent

Pour supprimer tous les articles associés à une catégorie à la suppression de la catégorie, on peut écrire :

class Categorie < ApplicationRecord
  has_many :articles, dependent: :destroy
end

qui supprimera les objets articles associés (et appellera donc les callbacks)

ou :

class Categorie < ApplicationRecord
  has_many :articles, dependent: :delete_all
end

qui supprimera directement les articles associés en base de données (et n’appellera pas les callbacks)

:counter_cache

Pour afficher le nombre d’associations sans faire de requête supplémentaire, on peut utiliser un « counter_cache » :

class Article < ApplicationRecord
  belongs_to :categorie, counter_cache: true
end

Il faut pour cela ajouter un champ posts_count dans la table catégorie (avec 0 comme valeur par défaut).

La valeur de posts_count sera mis à jour automatiquement quand on ajoute ou supprime un article à une catégorie.

has_and_belongs_to_many

Pour créer une table de liaison, on peut faire la migration :

rails g migration create_join_table_articles_tags article tag

et utiliser le has_and_belongs_to_many

class Article < ApplicationRecord
  has_and_belongs_to_many :tags
end
 
class Tag < ApplicationRecord
  has_and_belongs_to_many :articles
end

L’association has_many: :through permet de faire la même chose avec une classe de liaison. Cela peut être utile lorsqu’on veut stocker des choses dans la table d’association.

article.tags.delete(tag) supprime la liaison
article.tags.destroy(tag) supprime le tag et les liaisons

2 réflexions au sujet de « Ruby on Rails par Grafikart – quelques astuces »

    1. Merci pour ton commentaire ! N’hésite pas à regarder les vidéos, mon article n’étant pas un résumé : j’ai simplement noté les astuces que je ne connaissais pas et qui me semblaient intéressantes.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.