Reputation: 457
The stage:
A class including MongoId:
class Mission
include Mongoid::Document
include Mongoid::Timestamps
attr_accessor :distance
# ... other atts and methods ...
end
The problem:
In Rails c
:
$ missions = Mission.all # => get all missions
$ missions[0].object_id # => 70264434234840
$ missions[1].object_id # => 70264410073940
# (for this example I will use only 2 records)
# Now look their object_ids on this loop:
$ missions.each {|m| puts m.object_id} # => 70264350130200, 70264359017780
# Second test with this example again:
$ for m in ms do puts m.object_id end # => 70264374331020, 70264374320260
The object_id
isn't the same inside and out of the loop, and is different between both loops too. So if distance
attribute is set inside a bucle, out the bucle its value is nil
.
Aditional Information:
ActiveRecord and MongoId: This loop problem only occurs with MongoId, I tested the same example with ActiveRecord and the object_ids are the same inside and out the loop.
My deduction:
Each time object_id
is called, a different value is returned. I guess MongoId makes a new database query whenever a mission is instanced (missions[0]
), without using the instance inside the missions
is collection (Mongoid::Criteria)
Questions:
Upvotes: 0
Views: 174
Reputation: 434815
When you say this:
missions = Mission.all
you're just story a query in missions
. Then each time you access the query, Mongoid will access the database:
missions[0] # One database access
missions[1] # Another database access
If you want to work with an array of Mongoid model instances, then say so:
missions = Mission.all.to_a
Of course that can create a lot of Mongoid::Document
s so you need to be sure that that's what you want to do.
Normally you wouldn't care what the object_id
s were, you'd compare the Mongoid objects directly (i.e. obj1 == obj2
) or look at their id
s instead of their object_id
s.
Upvotes: 1