Quelle est la différence entre pluck et collect in Rails?

123

Voici deux exemples de codes.

Premier avec collect:

User.first.gifts.collect(&:id)

Deuxième avec pluck:

User.first.gifts.pluck(:id)

Y a-t-il une différence entre les performances ou autre chose?

Mohit Jain
la source

Réponses:

230

pluckest au niveau db. Il interrogera uniquement le champ particulier. Regarde ça .

Quand vous faites:

 User.first.gifts.collect(&:id)

Vous avez des objets avec tous les champs chargés et vous obtenez simplement les idremerciements à la méthode basée sur Enumerable.

Alors:

  • si vous n'avez besoin que du idavec Rails 4, utilisez ids:User.first.gifts.ids

  • si vous n'avez besoin que de certains champs avec Rails 4, utilisez pluck:User.first.gifts.pluck(:id, :name, ...)

  • si vous n'avez besoin que d'un seul champ avec Rails 3, utilisez pluck:User.first.gifts.pluck(:id)

  • si vous avez besoin de tous les champs, utilisezcollect

  • si vous avez besoin de certains champs avec Rails 4, utilisez toujours pluck

  • si vous avez besoin de certains champs avec Rails 3, utilisez selectetcollect

apnée
la source
"si vous avez besoin de certains champs, utilisez selectand collect" - ne pouvez-vous pas simplement utiliser pluckavec plusieurs attributs, comme pluck(:id, :name)?
Alexander
@AlexPopov - Rails 4+ prend plucken charge plusieurs champs, Rails 3 ne le fait pas, sauf si vous utilisez la solution de contournement de Ryan Lefevre
Marksiemers
3
Dans Rails 4, si vous ne avez besoin de la id, utilisez .idsRef doc: api.rubyonrails.org/classes/ActiveRecord/...
Ivan Chau
30

Oui. Selon les guides Rails , pluckconvertit directement un résultat de base de données en un array, sans construire d' ActiveRecordobjets. Cela signifie de meilleures performances pour une requête volumineuse ou souvent exécutée.

En plus de la réponse de @ apneadiving, pluckpeut prendre à la fois des noms de colonnes simples et multiples comme argument:

Client.pluck(:id, :name)
# SELECT clients.id, clients.name FROM clients
# => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']]
Compagnon étranger
la source
3

La différence fondamentale et principale est que Pluck s'applique au niveau de la base de données et collecte toutes les données, puis vous renvoie l'enregistrement lorsque vous avez besoin de tous les enregistrements, utilisez collect et lorsque peu de champs utilisent ensuite pluck

Thorin
la source
2

S'il y a un cas où vous utilisez peu d'attributs de l'enregistrement récupéré. Dans de tels cas, vous devez utiliser pluck.

User.collect(&:email)

Dans l'exemple ci-dessus, si vous n'avez besoin que d'un attribut de courrier électronique, vous perdez de la mémoire et du temps. Parce qu'il récupérera toutes les colonnes de la table utilisateur dans la base de données, alloue la mémoire pour chaque attribut (y compris les attributs que vous n'utiliserez jamais)

REMARQUE: pluckne renvoie pas ActiveRecord_Relation de l'utilisateur

Palden sifflé
la source