未定义的方法`find_each' for []:Array

时间:2014-05-23 12:46:28

标签: ruby-on-rails oracle

我的代码是这样的。

@deliveries = User.find_uniq_deliveries(...)
.
.
.
(many conditions added using 'named_scope' )
@deliveries.sort do |a,b|
.
.
end

主要问题是这取得了很多结果,并且给了甲骨文的例外情况,即' in'中不允许超过1000个元素。声明。 所以我尝试使用find_each批量获取

deliveries_list = [] 
@deliveries.find_each(:batch_size=999) do |delivery|
    deliveries_list.push(delivery)
end
@deliveries = deliveries_list

但这会给出异常

  

未定义的方法`find_each' for []:Array

正如你所看到的那样,对于rails(来自java)并不感兴趣,对我来说轨道完全没有意义。我该怎么做才能防止Oracle SQL错误但是获取数据

编辑:

  def find_uniq_deliveries(category,date,view)
    dels = []
    sent_deliveries.send("for_#{category}s").send("with_#{category}_status", view).for_date_range(date).collect(&:workflow_item).uniq.each do |m|
      dels << m.deliveries.first unless m.deliveries.empty?
    end
    dels.compact
  end

2 个答案:

答案 0 :(得分:3)

必须在Active Record Query结果上调用find_each。

您正在从find_uniq_deliveries返回一个数组,因此不支持find_each。

您需要重写查询,将find_each调用放在.collect(&amp;:workflow_item)之前。

另请参阅可链接方法的Active Record Query Interface:

http://guides.rubyonrails.org/active_record_querying.html

.collect方法会生成一个值数组,因此您无法在此之后放置find_each。

编辑:以下是如何重构代码以使用find_each

的快速示例

基本配方是:

  1. 在调用任何非查询方法(如collect)之前构建一个Active Record查询。

  2. 作为该查询的一部分,您将使用find_each以一种动态从数据库中获取批量结果的方式迭代结果集。

  3. 保存非Active Record调用,例如collect for last。您可以返回一组结果,但只知道您将无法使用此数组调用任何其他AR方法,例如命名范围。

  4. 以下是使用find_each并接受查询的find_uniq_deliveries示例:

     def find_uniq_deliveries(query,category,date,view)
       dels = []
       query.send("for_#{category}s").send("with_#{category}_status", view).for_date_range(date).find_each do |delivery|
         # do something with your delivery object and save result
         result = process_delivery(delivery)
         dels << result
       end
       dels.compact
     end
    

    您可以使用任何交付查询来调用它:

    query = Delivery.some_named_scope.some_other_scope
    find_uniq_deliveries(query,category,date,view)
    

答案 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|