我有一个ActiveRecord模型Language
,列id
和short_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
但我不确定这是否会浪费时间/内存/处理。
我的问题有两个:
请注意,出于我的特定目的, n 大约为200。
答案 0 :(得分:7)
在Rails 3.x中,您可以使用pluck
方法返回请求字段中的值,而无需实例化对象来保存它们。
这会给你一系列ID:
Language.where(short_code: short_codes.flatten).pluck(:id)
我应该提一下,在Rails 3.x中,你一次只能拔一列,但在Rails 4中你可以传递多列来进行挖掘。
顺便说一句,这是similar answer到similar 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)
ActiveRecord::Base.connection.execute("SQL CODE!")
在您诉诸此代码之前,首先对您的代码进行基准测试。
答案 5 :(得分:0)
这确实是一个选择问题。
是否过度杀戮,ActiveRecord 假设为你提供对象,因为它是一个ORM。和Ben说,如果你不想要对象,请使用原始SQL。