🎯 Intention


MaĂźtriser la diffĂ©rence entre un pluck et un select fera de vous un.e meilleur.e dĂ©veloppeur.se, capable d'Ă©crire des requĂȘtes plus performante dans vos apps.

Et ainsi, d'Ă©viter des problĂšmes de RAM potentiel

<aside> ✅ PrĂ©-requis

✅ Points clĂ©s


<aside> ⌛ Temps indicatif : 1h

</aside>

Etape

Visuel / Exemple


1ïžâƒŁÂ Utiliser la mĂ©thode Pluck pour rĂ©cupĂ©rer une liste de valeurs pour UNE colonne en particulier

Raison :

Un array est moins lourd qu'une collection d’objet

liste_prenom = Utilisateur.pluck(:prenom)
	**Utilisateur Pluck (2.4ms)**  SELECT "utilisateurs"."prenom" FROM "utilisateurs"
=> ["jean","arthur"]

liste_prenom.class
=> Array

liste_prenom[0]
=> "jean"

🔱 Utiliser Select pour rĂ©cupĂ©rer une sĂ©lection de plusieurs colonnes d'une table

Raison :

Manipuler un objet plutĂŽt qu’un array rendra le code plus comprĂ©hensible, plus maintenable

SĂ©lectionnĂ©s un nombre limitĂ© de colonne (plutĂŽt que l'ensemble des colonnes de la table) aura un effet bĂ©nĂ©fique sur l’efficacitĂ© de la requĂȘte SQL ainsi que le poids de l’objet Ruby rĂ©cupĂ©rĂ© et enregistrĂ© en RAM

utilisateurs = Utilisateur.select(:id, :prenom)
	**Utilisateur Load (1.8ms)**  SELECT "utilisateurs"."id", "utilisateurs"."prenom" FROM "utilisateurs"
=> [
	#<Utilisateur:0x0000000107f46408 id: 1, prenom: "jean">,
	#<Utilisateur:0x0000000107f46188 id: 2, prenom: "arthur">
]
utilisateurs.class
=> Utilisateur::ActiveRecord_Relation
utilisateur = utilisateurs.first

utilisateur.id
=> 1
utilisateur.prenom
=> "jean"
utilisateur.created_at
=> missing attribute 'created_at' for Utilisateur (ActiveModel::MissingAttributeError)

🔗 Utiliser Select pour faire une jointure

Raison :

Un pluck créé un array potentiellement grand et utiliserait de la RAM pour rien

Tandis que le select va faire l’opĂ©ration directement en SQL (donc de maniĂšre plus performante)

Il existe une rĂšgle Rubocop pour empĂȘcher l’utilisation de Pluck: Rails/PluckInWhere

# ✅ GOOD
utilisateurs_ids = Demande.where(urgente: true).select(:utilisateur_id)
Utilisateur.where(id: utilisateurs_ids)
	**Utilisateur Load**  SELECT "utilisateurs".*
										FROM "utilisateurs"
										WHERE "utilisateurs"."id" = (
											SELECT "demandes"."utilisateur_id"
											FROM "demandes"
											WHERE "demandes"."urgente" = true
										)
# ❌ BAD
utilisateurs_ids = Demande.where(urgente: true).pluck(:utilisateur_id)
	**Utilisateur Load**  SELECT "demandes"."utilisateur_id"
										FROM "demandes"
										WHERE "demandes"."urgente" = true
Utilisateur.where(id: utilisateurs_ids)
	**Utilisateur Load**  SELECT "utilisateurs".*
										FROM "utilisateurs"
										WHERE "utilisateurs"."id" = ?

❌ Erreurs type Ă  Ă©viter