CristianOrellanaBak
CristianOrellanaBak

Reputation: 457

Why MongoId models change its object_id on loop?

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:

  1. Why this happens? every explanation is welcome :)
  2. How can iterate its "MongoId objects" preserving the same mission instance inside and outside of loop? (as ActiveRecord do)

Upvotes: 0

Views: 174

Answers (1)

mu is too short
mu is too short

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::Documents so you need to be sure that that's what you want to do.

Normally you wouldn't care what the object_ids were, you'd compare the Mongoid objects directly (i.e. obj1 == obj2) or look at their ids instead of their object_ids.

Upvotes: 1

Related Questions