В чем разница между pluck и collect в Rails?

123

Вот два примера кода.

Первый с collect:

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

Второй с pluck:

User.first.gifts.pluck(:id)

Есть ли между ними разница в производительности или еще что-то?

Мохит Джайн
источник

Ответы:

230

pluckнаходится на уровне БД. Он будет запрашивать только конкретное поле. Смотрите это .

Когда вы это сделаете:

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

У вас есть объекты со всеми загруженными полями, и вы просто получаете idблагодарность за метод, основанный на Enumerable.

Так:

  • если вам нужен толькоid Rails 4, используйте ids:User.first.gifts.ids

  • если вам нужны только некоторые поля с Rails 4, используйте pluck:User.first.gifts.pluck(:id, :name, ...)

  • если вам нужно только одно поле с Rails 3, используйте pluck:User.first.gifts.pluck(:id)

  • если вам нужны все поля, используйтеcollect

  • если вам нужны поля с Rails 4, все равно используйте pluck

  • если вам нужны поля с Rails 3, используйте selectиcollect

apneadiving
источник
"если вам нужны поля, используйте selectand collect" - нельзя просто использовать pluckс несколькими атрибутами, например pluck(:id, :name)?
Александр
@AlexPopov - Rails 4+ поддерживает pluckнесколько полей, Rails 3 - нет, если вы не используете обходной путь Райана Лефевра
Markiemers
3
В Rails 4, если вам нужен только файлid , используйте .idsRef doc: api.rubyonrails.org/classes/ActiveRecord/…
Иван Чау,
30

Да. Согласно руководствам Rails , pluckнапрямую преобразует результат базы данных в файл array, без создания ActiveRecordобъектов. Это означает лучшую производительность для большого или часто выполняемого запроса.

В дополнение к ответу @apneadiving в pluckкачестве аргумента может быть указано как одно, так и несколько имен столбцов:

Client.pluck(:id, :name)
# SELECT clients.id, clients.name FROM clients
# => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']]
Товарищ незнакомец
источник
3

Основное и главное отличие состоит в том, что Pluck применяется на уровне базы данных и собирает, получает все данные, а затем возвращает вам запись, когда вам нужно, чтобы все записи использовали сбор, а когда несколько полей, затем используйте pluck

Торин
источник
2

Если есть случай, когда вы используете несколько атрибутов полученной записи. В таких случаях вам следует использовать pluck.

User.collect(&:email)

В приведенном выше примере, если вам нужен только атрибут электронной почты, вы тратите память и время. Поскольку он будет извлекать все столбцы из пользовательской таблицы в базе данных, выделяет память для каждого атрибута (включая атрибуты, которые вы никогда не будете использовать)

ПРИМЕЧАНИЕ: pluckне возвращает ActiveRecord_Relation пользователя

Чимед Палден
источник