Qual é a diferença entre pluck e collect no Rails?


123

Aqui estão dois códigos de amostra.

Primeiro com collect:

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

Segundo com pluck:

User.first.gifts.pluck(:id)

Existe alguma diferença entre eles no desempenho ou algo mais?

Respostas:


230

pluckestá no nível db. Ele somente consultará o campo específico. Veja isso .

Quando você faz:

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

Você tem objetos com todos os campos carregados e simplesmente recebe os idagradecimentos ao método baseado em Enumerable.

Assim:

  • se você precisar apenas do idRails 4, use ids:User.first.gifts.ids

  • se você precisar apenas de alguns campos com o Rails 4, use pluck:User.first.gifts.pluck(:id, :name, ...)

  • se você precisar de apenas um campo com o Rails 3, use pluck:User.first.gifts.pluck(:id)

  • se você precisar de todos os campos, usecollect

  • se você precisar de alguns campos com o Rails 4, ainda use pluck

  • se você precisar de alguns campos com o Rails 3, use selectecollect


"se você precisar de alguns campos, use select e collect" - você não pode simplesmente usar pluckcom vários atributos, como pluck(:id, :name)?
1011 Alexander

@AlexPopov - Rails 4+ suportes plucking vários campos, Rails 3 não, a menos que você usar solução de Ryan Lefevre
marksiemers

3
No Rails 4, se você única precisa do id, uso .idsRef doc: api.rubyonrails.org/classes/ActiveRecord/...
Ivan Chau

30

Sim. De acordo com os guias do Rails , pluckconverte diretamente um resultado do banco de dados em um array, sem construir ActiveRecordobjetos. Isso significa melhor desempenho para uma consulta grande ou frequentemente em execução.

Além da resposta de @ apneadiving, pluckpode usar nomes de coluna únicos e múltiplos como argumento:

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

3

A diferença básica e principal é que Pluck se aplica no nível de banco de dados e coleta, obtém todos os dados e retorna o registro para você quando você precisar que todos os registros usem collect e quando alguns campos usem pluck


2

Se houver um caso em que você esteja usando poucos atributos do registro recuperado. Nesses casos, você deve usar pluck.

User.collect(&:email)

No exemplo acima, se você só precisa do atributo de email, está perdendo tempo e memória. Como ele recupera todas as colunas da tabela de usuários no banco de dados, aloca a memória para cada atributo (incluindo os atributos que você nunca usará)

NOTA: plucknão retorna ActiveRecord_Relation do usuário

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.