Лучшие практики для получения списка идентификаторов из модели ActiveRecord - PullRequest
4 голосов
/ 19 июня 2009

У меня есть модель ActiveRecord Language, со столбцами id и short_code (есть другие столбцы, но они не имеют отношения к этому вопросу). Я хочу создать метод, который получит список коротких кодов и вернет список идентификаторов. Меня не волнуют ассоциации, мне просто нужно получить массив, который выглядит как [1, 2, 3, ...].

Моей первой мыслью было сделать что-то вроде

def get_ids_from_short_codes(*short_codes)
  Language.find_all_by_short_code(short_codes.flatten, :select => 'id').map(&:id)
end

но я не уверен, что это напрасно тратит время / память / обработку.

У меня двоякий вопрос:

  1. Есть ли способ запустить поиск ActiveRecord, который будет просто возвращать массив определенного столбца таблицы, а не создавать экземпляры объектов?
  2. Если это так, стоило бы на самом деле собирать массив длиной n вместо создания n объектов ActiveRecord?

Обратите внимание, что для моей конкретной цели n будет примерно 200.

Ответы [ 6 ]

8 голосов
/ 21 ноября 2013

В Rails 3.x вы можете использовать метод pluck, который возвращает значения из запрошенного поля без создания экземпляров объектов для их хранения.

Это даст вам массив идентификаторов:

Language.where(short_code: short_codes.flatten).pluck(:id)

Следует отметить, что в Rails 3.x вы можете собирать только один столбец за раз, но в Rails 4 вы можете передавать несколько столбцов для извлечения.

Кстати, вот аналогичный ответ на аналогичный вопрос

6 голосов
/ 19 июня 2009

Честно говоря, для 200 записей я бы об этом не беспокоился. Когда вы получаете 2000, 20 000 или 200 000 записей - тогда вы можете беспокоиться об оптимизации.

Убедитесь, что у вас есть шорткод, проиндексированный в вашей таблице.

Если вы все еще беспокоитесь о производительности, посмотрите на файл development.log и посмотрите, какие номера баз данных для этого конкретного вызова. Вы можете настроить запрос и посмотреть, как он влияет на производительность в журнале. Это должно дать вам приблизительную оценку производительности.

5 голосов
/ 04 января 2010

если вы используете ассоциации, вы можете получить необработанные идентификаторы непосредственно из ActiveRecord. eg.:

class User < ActiveRecord::Base
  has_many :users
end

irb:=> User.find(:first).user_ids
irb:>> [1,2,3,4,5]
5 голосов
/ 19 июня 2009

Согласен с предыдущим ответом, но если вам абсолютно необходимо, вы можете попробовать это

sql = Language.send(:construct_finder_sql, :select => 'id', :conditions => ["short_code in (?)", short_codes])
Language.connection.select_values(sql)

Немного отвратительно, но это не создает объекты в памяти.

3 голосов
/ 19 июня 2009

Фил прав насчет этого, но если вы обнаружите, что это проблема. Вы можете отправить необработанный SQL-запрос в базу данных и работать на уровне ниже ActiveRecord. Это может быть полезно для подобных ситуаций.

ActiveRecord::Base.connection.execute("SQL CODE!")

Сначала сравните ваш код, прежде чем прибегнуть к этому.

0 голосов
/ 19 июня 2009

Это действительно вопрос выбора.

Превышение или нет, ActiveRecord предполагается , чтобы дать вам объекты, так как это ORM. И, как сказал Бен, если вам не нужны объекты, используйте сырой SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...