Search code examples
arraysrubyruby-on-rails-3.2mongoidenumerator

can't convert Enumerator into Array


While working on one application I am getting this error:

can't convert Enumerator into Array

Here is my code, mr_collection is MongoID query.

mr_collection = self.where(query).map_reduce(map, reduce).finalize(finalize).out({:replace => 'mr_results'})
paginator = WillPaginate::Collection.new(page, limit, collection_count)

collection = mr_collection.find(
   :sort => sort,
   :limit => limit,
   :skip => skip
)
paginator.replace(collection)

While getting mr_collection, if I inspect the result mr_collection gives me:

[   
   {"_id"=>1.0, "value"=>{"s"=>4.2, "p"=>14.95, "pml"=>0.01993}}, 
   {"_id"=>2.0, "value"=>{"s"=>3.7, "p"=>12.9, "pml"=>0.0172}}, 
   {"_id"=>3.0, "value"=>{"s"=>4.2, "p"=>12.9, "pml"=>0.0172}}, 
   {"_id"=>4.0, "value"=>{"s"=>4.0, "p"=>11.95, "pml"=>0.01593}}, 
   {"_id"=>300.0, "value"=>{"s"=>0.0, "p"=>8.95, "pml"=>0.01193}}, 
]

While getting collection, if I inspect the result collection gives me:

#<Enumerator: []:find({:sort=>[["value.s", :desc], ["value.pml", :asc]], :limit=>10, :skip=>0})>

I am getting error on the line paginator.replace(collection). I'm using Ruby 1.9.3 & Rails 3.2.6.


Solution

  • collection is an Enumerator which obviously can't convert into an Array, which is what replace expects.

    Here are the comments from the rubydocs:

    Enumerable#find(ifnone = nil) { |e| ... }

    Passes each entry in enum to block. Returns the first for which block is not false. If no object matches, calls ifnone and returns its result when it is specified, or returns nil otherwise.

    If no block is given, an enumerator is returned instead.

    Therefore you have two options:

    1. If you want all elements, yield from the Enumerator to an Array.
    2. If you only want the first match, supply a block that determines what the match is.

    Hope this helps.

    (Moral of the story: always read the docs!)