Lorsque l'on travaille avec Ruby on Rails, l'une des fonctionnalités les plus puissantes à la disposition des développeurs est Active Record. Elle simplifie les interactions avec les bases de données en vous permettant d'écrire des requêtes en utilisant Ruby au lieu de SQL. Cependant, au fur et à mesure que les applications se développent, il est souvent nécessaire d'extraire des données de plusieurs tables connexes. C'est là que l'Active Record rejoint entrent en jeu.
Dans ce guide, nous allons explorer les jointures Rails en profondeur, comprendre comment elles fonctionnent dans l'interface de requête Active Record et apprendre à les utiliser efficacement dans des scénarios réels.
Que sont les jointures dans Rails ?
Une jointure est une opération de base de données qui combine les lignes de deux tables ou plus sur la base d'une colonne connexe. Dans Rails, les jointures vous permettent d'extraire efficacement des enregistrements associés sans écrire de code SQL brut.
Prenons l'exemple de deux modèles :
- Utilisateur
- Poste
Un utilisateur a plusieurs messages, et un message appartient à un utilisateur. Si vous souhaitez rechercher des utilisateurs avec leurs messages, vous pouvez utiliser des jointures.
Types de jointures dans Rails
Rails prend principalement en charge les types de jointures suivants :
1. INNER JOIN (jointures)
La jointure la plus couramment utilisée dans Rails est la jointure interne (INNER JOIN).
Utilisateur.joins(:posts)
Cette requête ne renvoie que les utilisateurs qui ont au moins un message.
Équivalent SQL :
SELECTIONNER utilisateurs.* DE utilisateurs INNER JOINDRE des postes ON posts.user_id = utilisateurs.identifiant;
Points clés :
- Retourne uniquement les enregistrements correspondants
- Exclut les utilisateurs sans messages
2. LEFT OUTER JOIN (left_joins)
Si vous souhaitez inclure tous les utilisateurs, même ceux qui n'ont pas de messages, utilisez les jointures gauches.
User.left_joins(:posts)
Équivalent SQL :
SELECTIONNER utilisateurs.* DE utilisateurs GAUCHE EXTÉRIEUR JOINDRE des postes ON posts.user_id = users.identifiant;
Points clés :
- Inclut tous les utilisateurs
- Les messages peuvent être NULS pour les utilisateurs qui n'ont pas de messages
3. Inclusions et jointures
Rails fournit des inclusions pour le chargement anticipé, qui est souvent confondu avec les jointures.
User.includes(:posts)
Différence :
- jointures → filtrage des données au niveau de la base de données
- comprend → empêche N+1 requêtes
Filtrer avec des jointures
Vous pouvez combiner des jointures avec des conditions pour filtrer les résultats.
User.joins(:posts).où(des postes : { publié : true })Cette option renvoie aux utilisateurs qui ont publié des articles.
Adhésion à plusieurs associations
Rails permet d'enchaîner plusieurs jointures.
User.joins(des postes : :commentaires)
Il s'agit de joindre les utilisateurs → les messages → les commentaires.
Équivalent SQL :
SELECTIONNER utilisateurs.* DE utilisateurs INNER JOINDRE des postes ON posts.user_id = users.identifiant INNER JOINDRE commentaires ON comments.post_id = posts.identifiant;
Sélection de colonnes spécifiques
Par défaut, les jointures renvoient toutes les colonnes de la table de base.
User.joins(:posts).select("users.name, posts.title")Conseil :
Utilisez cette fonction pour optimiser les performances et réduire l'utilisation de la mémoire.
Utilisation de la distinction avec les jointures
Les jointures peuvent renvoyer des enregistrements en double.
User.joins(:posts).distinct
Cela permet de s'assurer que des utilisateurs uniques sont renvoyés.
Utilisation de groupes et de comptages
Vous pouvez agréger des données à l'aide de jointures.
User.joins(:posts).group("users.id").countExemple de sortie :
{1 => 5, 2 => 3}
Cela montre le nombre de messages par utilisateur.
Joints Rails avancés avec les fragments SQL
Parfois, les aides Active Record ne suffisent pas.
User.joins("INNER JOIN posts ON posts.user_id = users.id AND posts.published = true")Cas d'utilisation :
- Conditions complexes
- Optimisation des performances
Utilisation de jointures avec des champs d'application
Les portées permettent de réutiliser les joints.
classe Utilisateur < ApplicationRecord
a_plusieurs :posts
champ d'application :with_published_posts, -> {
joins(:posts).où(des postes : { publié : true })
}
finUsage:
Utilisateur.avec_postes_publiés
Éviter les requêtes N+1
Les requêtes N+1 constituent un problème de performance courant.
Mauvais exemple :
users = User.all
users.each faire |user|
utilisateur.posts.each faire |post|
met post.title
fin
finSolution :
User.includes(:posts)
Jointures vs inclusions vs précharge
| Méthode | Objectif | Comportement SQL |
|---|---|---|
| rejoint | Filtrage | INNER JOIN |
| jointures_gauche | Inclure tous les | JOINTURE EXTERNE GAUCHE |
| comprend | Éviter N+1 | Requêtes multiples ou JOIN |
| précharge | Toujours séparer les requêtes | Non JOIN |
Considérations sur les performances
1. L'indexation
S'assurer que les clés étrangères sont indexées :
add_index :posts, :user_id
2. Éviter le surchargement
Utilisez la fonction de sélection pour limiter les colonnes.
3. Utiliser le filtrage au niveau de la base de données
Il faut toujours préférer les conditions de jonction.
Les pièges les plus fréquents
1. Duplicata d'enregistrements
Utiliser .distinct si nécessaire.
2. Colonnes ambiguës
Utiliser des préfixes de table :
select("users.id, posts.id AS post_id")3. Mauvais type de jointure
Choisissez avec soin les jointures et les jointures gauches.
Exemple concret
Récupérer les utilisateurs ayant publié plus de 3 articles :
User.joins(:posts)
.où(des postes : { publié : true })
.group("users.id")
.having("COUNT(posts.id) > 3")
Meilleures pratiques pour les jointures Rails
- Utiliser les jointures pour le filtrage
- Utiliser les inclusions pour le chargement anticipé
- Toujours tester les performances des requêtes
- Faire en sorte que les requêtes soient lisibles
- Utiliser les champs d'application pour la réutilisation
Conclusion
Les jointures Rails sont une fonctionnalité puissante de l'interface de requête Active Record qui permet aux développeurs d'interroger efficacement des données liées entre plusieurs tables. En comprenant les différences entre les jointures, les jointures gauches et les inclusions, vous pouvez écrire des requêtes de base de données optimisées et évolutives.
La maîtrise des joints ne permet pas seulement d'améliorer les performances, mais aussi de rendre votre vie plus agréable. Applications Rails plus facile à maintenir et plus efficace. Qu'il s'agisse d'une petite application ou d'un grand système d'entreprise, il est essentiel de savoir comment utiliser efficacement les jointures pour réussir.
RailsCarma est un leader Société de développement Ruby on Rails spécialisée dans la création d'applications web évolutives et performantes. Avec une expertise approfondie dans Active Record et des techniques d'optimisation de base de données comme les jointures, RailsCarma aide les entreprises à concevoir des architectures de données efficaces, à réduire la charge des requêtes et à améliorer la performance des applications. Leur équipe se concentre sur les meilleures pratiques, un code propre et un développement axé sur la performance afin de garantir des applications Rails robustes et faciles à maintenir pour les startups comme pour les entreprises.