#ruby-on-rails #ruby-on-rails-3 #activerecord
#ruby-on-rails #ruby-on-rails-3 #activerecord
Вопрос:
Чтобы получить номера счетов выбранных заданий, я делаю:
Job.where(...).map(amp;:invoice_number)
Поскольку номера счетов -это все, что мне нужно, я подумал добавить select(:invoice_number)
(я предполагаю, что таким образом SQL-запрос становится более эффективным):
Job.where(...).select(:invoice_number).map(amp;:invoice_number)
Есть ли лучший способ сделать то же самое? ( .select(:invoice_number).map(amp;:invoice_number)
часть кажется мне неэффективной)
Ответ №1:
Вы всегда могли бы использовать select_values
. Что-то похожее на:
Job.connection.select_values(Job.where(...).select(:invoice_number).to_sql)
Это позволяет избежать создания экземпляров объектов ActiveRecord.
Комментарии:
1. Увлекательно… есть идеи, действительно ли это более эффективно, чем исходный код poster?
Ответ №2:
Я знаю, что этот вопрос довольно старый, но на случай, если кто-нибудь еще проверит это, этого можно достичь с помощью pluck
(http://apidock.com/rails/ActiveRecord/Calculations/pluck ). Согласно http://edgeguides.rubyonrails.org/active_record_querying.html#pluck « pluck
позволяет заменить код типа: Client.select(:id).map(amp;:id)
на Client.pluck(:id)
«
Комментарии:
1. Сейчас абсолютно верно, но только начиная с версии 3.2, которая была выпущена через некоторое время после первоначального вопроса (в начале 2012). Если вы по какой-то причине застряли при работе с устаревшими Rails, вам понадобится другой метод.
Ответ №3:
Хотелось бы, чтобы было доказано обратное, но.. Я не думаю, что это возможно
Поскольку все активные методы записи являются цепными, метод, который возвращает массив строк, нарушил бы это. Если бы такой метод существовал, то его не было бы в AR, я не могу придумать, где еще искать..
Ответ №4:
Вы можете использовать GROUP_CONCAT.
invoice_numbers = Job.where(...).select('group_concat(invoice_number) as invoice_numbers').
first.invoice_numbers.split(',').map(amp;:to_i)
Этот подход слишком длинный и не очень очевидный, но он будет выполняться быстрее, чем
Job.where(...).select(:invoice_number).map(amp;:invoice_number)