В чем разница между сбоями и сбором в Rails?
Вот два примера кода.
Сначала с collect
:
User.first.gifts.collect(&:id)
Второй с pluck
:
User.first.gifts.pluck(:id)
Есть ли разница между ними в производительности или чем-то еще?
Ответы
Ответ 1
pluck
находится на уровне db. Он будет запрашивать только конкретное поле. См. это.
Когда вы выполните:
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)
-
если вам нужны поля all, используйте collect
-
если вам нужны поля с Rails 4, используйте pluck
-
если вам нужны поля с Rails 3, используйте select
и collect
Ответ 2
Да. В соответствии с направляющими 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 применяется на уровне db и собирает все данные и затем возвращает вам запись
когда вам понадобятся все записи, используйте коллекцию, и когда несколько полей затем используют pluck
Ответ 4
Если есть случай, когда вы используете несколько атрибутов найденной записи. В таких случаях вы должны использовать pluck
.
User.collect(&:email)
В приведенном выше примере, если вам нужен только атрибут электронной почты, чем вы тратите впустую память и время. Поскольку он извлекает все столбцы из пользовательской таблицы в базе данных, выделяет память для каждого атрибута (включая атрибуты, которые вы никогда не будете использовать)
ПРИМЕЧАНИЕ: pluck
не возвращает ActiveRecord_Relation пользователя