¿Cuál es la diferencia entre arrancar y recoger en Rails?

123

Aquí hay dos códigos de muestra.

Primero con collect:

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

Segundo con pluck:

User.first.gifts.pluck(:id)

¿Hay alguna diferencia entre ellos en el rendimiento o alguna otra cosa?

Mohit Jain
fuente

Respuestas:

230

pluckestá en el nivel de base de datos. Solo consultará el campo en particular. Mira esto .

Cuando tu lo hagas:

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

Tiene objetos con todos los campos cargados y simplemente obtiene las idgracias al método basado en Enumerable.

Entonces:

  • si solo necesita el idcon Rails 4, use ids:User.first.gifts.ids

  • si solo necesita algunos campos con Rails 4, use pluck:User.first.gifts.pluck(:id, :name, ...)

  • si solo necesita un campo con Rails 3, use pluck:User.first.gifts.pluck(:id)

  • si necesita todos los campos, usecollect

  • si necesita algunos campos con Rails 4, aún use pluck

  • si necesita algunos campos con Rails 3, use selectycollect

apneadiving
fuente
"si necesita algunos campos, use selectand collect" - ¿no puede simplemente usar pluckcon múltiples atributos, como pluck(:id, :name)?
Alexander
@AlexPopov - Rails 4+ admite pluckmúltiples campos, Rails 3 no, a menos que use la solución alternativa de Ryan Lefevre
marchas del
3
En Rails 4, si solo necesita el id, use .idsRef doc: api.rubyonrails.org/classes/ActiveRecord/…
Ivan Chau
30

Si. Según las guías de Rails , pluckconvierte directamente el resultado de una base de datos en un array, sin construir ActiveRecordobjetos. Esto significa un mejor rendimiento para una consulta grande o que se ejecuta con frecuencia.

Además de la respuesta de @ apneadiving, pluckpuede tomar nombres de columnas simples y múltiples como argumento:

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

La diferencia básica y principal es que Pluck se aplica en el nivel db y collect para obtener todos los datos y luego devolverle el registro cuando necesite que todos los registros usen collect y cuando pocos campos usen pluck

Thorin
fuente
2

Si hay un caso en el que está utilizando pocos atributos del registro recuperado. En tales casos debes usar pluck.

User.collect(&:email)

En el ejemplo anterior, si solo necesita un atributo de correo electrónico, está desperdiciando memoria y tiempo. Debido a que recuperará todas las columnas de la tabla de usuario en la base de datos, asigna la memoria para cada atributo (incluidos los atributos que nunca usará)

NOTA: pluckno devuelve ActiveRecord_Relation del usuario

Chimed Palden
fuente