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
where
par exemple)<aside> â Temps indicatif : 1h
</aside>
pluck
retourne un arrayRaison :
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"
select
retourne une collection dâobjet qui contiennent seulement les attributs sĂ©lectionnĂ©sRaison :
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)
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" = ?