【发布时间】:2009-03-27 06:16:46
【问题描述】:
在 ruby on rails 中,所有 has_many :widgets 方法都会生成 object.widgets 方法和 object.widget_ids 方法。
后一种方法非常有用,因为它绕过了 ActiveRecord 对象的创建并运行更快的查询。使用:select 选项可以提高查询速度,但是在生成对象而不是整数时,ruby 仍然会分配更多的内存。
例如
User has_many :historical_sessions:
>> Benchmark.measure { User.find(4).historical_sessions.map(&:id) }
HistoricalSession Load (131.0ms) SELECT * FROM `historical_sessions` WHERE (`historical_sessions`.user_id = 4)
=> #<Benchmark::Tms:0xbe805c0 @cutime=0.0, @label="", @total=1.996, @stime=0.0150000000000006, @real=2.09599995613098, @utime=1.981, @cstime=0.0>
(2.1 seconds)
>> Benchmark.measure { User.find(4).historical_session_ids }
HistoricalSession Load (34.0ms) SELECT `historical_sessions`.id FROM `historical_sessions` WHERE (`historical_sessions`.user_id = 4)
=> #<Benchmark::Tms:0x11e6cd94 @cutime=0.0, @label="", @total=1.529, @stime=0.032, @real=1.55099987983704, @utime=1.497, @cstime=0.0>
(1.6 seconds)
(结果集为67353个对象)
有没有办法在使用 named_scopes 时出现相同的行为?
例如,
User named_scope :recent
User.recent (Exists)
User.recent_ids (Does not exist)
我目前在命名范围结果集中获取对象 ID 的方式是: HistoricalSession.recent.map(&:id)。这与上面后一个示例中所做的基本相似,并且显然效率不高。我不想构建整个 HistoricalSession 对象,最终我只需要一个 id 数组。
另一种实现可能是新的 .find 方法。例如,HistoricalSession.recent.find_attributes(:id)。此方法将替换 select 语句以仅选择指定的值,并将缩短 ActiveRecord 对象的创建以仅返回一个数组。
有什么建议吗?这可能是一个简单的插件吗?
【问题讨论】:
标签: ruby-on-rails ruby activerecord named-scope