这是由其他人编写的现有代码,我正在尝试增强它。我是一名从事Ruby on Rails的java开发人员,所以要体谅他人。
我有这样的实体
User
交付实体,
Delivery
belongs_to :user
named_scope :for_abcs, :conditions => {'deliveries.xyz_type' => ['Xyz1', 'Xyz2']},
定义了许多这样的命名范围。
现在以这样的方式获取交付
@deliveries = current_user.deliveries.send("for_abcs").with(:xyz, :sender, :receiver)
...
...
...
# few other conditions added to @deliveries
终于
@deliveries.sort(...)
这种方式占用了巨大的sql并且出现了性能问题。我想使用find_each
,但find_each
仅适用于Ruby on Rails中的Active Entity,如何在没有太多代码更改的情况下实现此目标(如果可能)
早些时候我曾经做过
Delevery.find_each
无论在哪里
Delivery.find
现在我无法做到,因为它是一个数组,在Ruby on Rails中执行该操作的解决方法或正确的过程是什么。
编辑: 我尝试了什么:
deliveries_temp = []
@deliveries.find_each(:batch_size=>999) do |delivery_temp|
deliveries_temp.push(delivery_temp)
end
这给了我错误
undefined method `find_each' for []:Array
答案 0 :(得分:1)
find_each
应该可以处理返回Relation(包括范围)的任何内容。
@deliveries = current_user.deliveries.for_abcs(:xyz, :sender, :receiver).find_each
听起来你正在使用Rails 2.3。 find_each
是2.3中的类方法,因此您需要一种从范围中提取条件并将其传递给find_each
的方法。我找到了an article that looks promising,所以试一试:
Delivery.find_each(current_user.deliveries.for_abcs.scope(:find))
另外,我还不确定#with
正在做什么。也许它应该是#includes
?
答案 1 :(得分:0)
经过一周的研究,通过查看源代码了解named_scopes。我明白了问题所在。 @deliveries
是类ActiveRecord::NamedScope::Scope
的对象。这个类没有find_each方法。所以我在Delivery
模型文件中为限制和偏移写了一个新的named_scope,如下所示:
named_scope :limit_and_offset, lambda { |lim,off| { :limit => lim, :offset=>off } }
在此之后,我在一个循环中调用它来传递偏移和限制,例如。第一个循环有offset = 0,limit = 999,第二个循环有offset = 999,limit = 999。我将所有结果添加到一个emptry数组中。此循环继续,直到结果大小小于限制值。这是按照我想要的方式批量工作。
set = 1
total_deliveries = []
set_limit=999
original_condition = @deliveries
loop do
offset = (set-1) * set_limit
temp_condition = original_condition.limit_and_offset(set_limit,offset)
temp_deliveries = temp_condition.find(:all)
total_deliveries+= temp_deliveries
set += 1
break if temp_deliveries.size < set_limit
end
@deliveries = total_deliveries.sort do |a, b|