从ActiveRecord模型获取ID列表的最佳实践

时间:2009-06-19 15:01:26

标签: ruby-on-rails optimization activerecord

我有一个ActiveRecord模型Language,列idshort_code(还有其他列,但它们与此问题无关)。我想创建一个方法,给出一个短代码列表,并返回一个ID列表。我不关心关联,我只需要一个看起来像[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对象?
  3. 请注意,出于我的特定目的, n 大约为200。

6 个答案:

答案 0 :(得分:7)

在Rails 3.x中,您可以使用pluck方法返回请求字段中的值,而无需实例化对象来保存它们。

这会给你一系列ID:

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

我应该提一下,在Rails 3.x中,你一次只能拔一列,但在Rails 4中你可以传递多列来进行挖掘。

顺便说一句,这是similar answersimilar question

答案 1 :(得分:6)

老实说,对于200条记录,我不担心。当你获得2000,200或200,000条记录时 - 那么你可以担心优化。

确保您的表格中包含short_code索引。

如果您仍然关注性能,请查看development.log并查看该特定调用的数据库编号。您可以调整查询并查看它如何影响日志中的性能。这应该可以粗略估计性能。

答案 2 :(得分:5)

同意之前的回答,但如果你绝对必须,你可以试试这个

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

虽然有点难看,但它不会创建内存中的对象。

答案 3 :(得分:5)

如果您正在使用关联,则可以直接从ActiveRecord获取原始ID。 例如:

class User < ActiveRecord::Base
  has_many :users
end

irb:=> User.find(:first).user_ids
irb:>> [1,2,3,4,5]

答案 4 :(得分:3)

菲尔对此是正确的,但如果你确实发现这是一个问题。您可以将原始SQL查询发送到数据库,并在ActiveRecord下面的级别工作。这对于这种情况很有用。

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

在您诉诸此代码之前,首先对您的代码进行基准测试。

答案 5 :(得分:0)

这确实是一个选择问题。

是否过度杀戮,ActiveRecord 假设为你提供对象,因为它是一个ORM。和Ben说,如果你不想要对象,请使用原始SQL。