Mongoid returns _id field only in has_many relation when identity map enabled

579 views Asked by At

Mongoid 2.4.4 Rails 3.2.1 MongoDB 2.0.1

I have 3 models:

Authentication、Favorite and Content。

It just like a Many to Many relations from Authentication to Content through Favorite.

When I query like this :

@favorites = Favorite.any_in(authentication_id: list).includes(:content, :authentication).desc(:collected_at).page params[:page]

@favorites works fine

@favorites's content also works fine.

But @favorites' authentication only has _id, all of others field is nil

When I set identity_map_enabled: false, it fixed.

Is this a bug for identity_map?

Here is some information for tracert,
You can see f.weibo.name is nil when identity map enabled.

How can I fix this issue when identity_map_enabled: true?

--------------------- Models ---------------------------------

class Authentication
 include Mongoid::Document
 include Mongoid::Timestamps
 include Service::Weibo::Api::Oauth
 cache

 field :_id, :type => Integer
 field :uid, :type => Integer
 field :name, :type => String

 has_many :favorites
end

class Favorite
 include Mongoid::Document
 include Mongoid::Timestamps
 cache
 paginates_per 20

 field :collected_at, :type => Time, :default => Time.now

 belongs_to :authentication
 belongs_to :content

 def weibo
   self.authentication
 end

 def weibo_ids
   self.authentication_ids
 end

end

class Content
 include Mongoid::Document
 include Mongoid::Timestamps
 cache

 field :text, :type => String

 has_many :favorites
end

-------------- Debug code: -----------------------

    logger.debug "list: #{list}"
   @favorites = Favorite.any_in(authentication_id:
list).includes(:content, :authentication).desc(:collected_at).page
params[:page]
   @favorites.each do |f|
     logger.debug f
     logger.debug "name: #{f.weibo.name}"

    logger.debug "before name: #{@favorites.first.weibo.name}"
    clist =  [764826410]
 #    cf = Favorite.any_in(content_id:
clist).includes(:content, :authentication)
    logger.debug "after query name: #{@favorites.first.weibo.name}"
 #   cf.each {|f| logger.debug "cname: #{f.weibo.name}" }
    logger.debug "after logger name: #{@favorites.first.weibo.name}"

--------- Debug code end ---------------------

--------- LOG identity_map_enabled: true --------------------

[0408 12:42:38(3129)DEBUG] list: [1751951491]
 15 [0408 12:42:38(3129)DEBUG] MONGODB
weibofav_development['system.namespaces'].find({})
 16 [0408 12:42:38(3129)DEBUG] MONGODB
weibofav_development['favorites'].find({:authentication_id=>{"$in"=>[1751951491]}}).limit(20).sort([[:collected_at, :desc]])
 17 [0408 12:42:38(3129)DEBUG] #<Favorite _id:
4f80c04953cd210b56000003, _type: nil, created_at: 2012-04-07 22:31:37
UTC, updated_at: 2012-04-07 22:31:37 UTC, collected_at
   : 2012-04-07 20:46:37 UTC, authentication_id: 1751951491,
content_id: 3418929751988429>
 18 [0408 12:42:38(3129)DEBUG] name:
 19 [0408 12:42:38(3129)DEBUG] MONGODB
weibofav_development['favorites'].find({:authentication_id=>{"$in"=>[1751951491]}}).limit(-1).sort([[:collected_at, :desc]])
 20 [0408 12:42:38(3129)DEBUG] before name:
 21 [0408 12:42:38(3129)DEBUG] MONGODB
weibofav_development['favorites'].find({:authentication_id=>{"$in"=>[1751951491]}}).limit(-1).sort([[:collected_at, :desc]])
 22 [0408 12:42:38(3129)DEBUG] after query name:
 23 [0408 12:42:38(3129)DEBUG] MONGODB
weibofav_development['favorites'].find({:authentication_id=>{"$in"=>[1751951491]}}).limit(-1).sort([[:collected_at, :desc]])
 24 [0408 12:42:38(3129)DEBUG] after logger name:
 25 [0408 12:42:38(3129)DEBUG] #<Favorite _id:
4f80c04953cd210b56000005, _type: nil, created_at: 2012-04-07 22:31:37
UTC, updated_at: 2012-04-07 22:31:37 UTC, collected_at
   : 2012-04-07 20:46:37 UTC, authentication_id: 1751951491,
content_id: 3418840442279122>
 26 [0408 12:42:38(3129)DEBUG] name:
 27 [0408 12:42:38(3129)DEBUG] MONGODB
weibofav_development['favorites'].find({:authentication_id=>{"$in"=>[1751951491]}}).limit(-1).sort([[:collected_at, :desc]])
 28 [0408 12:42:38(3129)DEBUG] before name:
 29 [0408 12:42:38(3129)DEBUG] MONGODB
weibofav_development['favorites'].find({:authentication_id=>{"$in"=>[1751951491]}}).limit(-1).sort([[:collected_at, :desc]])
 30 [0408 12:42:38(3129)DEBUG] after query name:
 31 [0408 12:42:38(3129)DEBUG] MONGODB
weibofav_development['favorites'].find({:authentication_id=>{"$in"=>[1751951491]}}).limit(-1).sort([[:collected_at, :desc]])
 32 [0408 12:42:38(3129)DEBUG] after logger name:
 33 [0408 12:42:38(3129)DEBUG] #<Favorite _id:
4f80c04953cd210b56000007, _type: nil, created_at: 2012-04-07 22:31:37
UTC, updated_at: 2012-04-07 22:31:37 UTC, collected_at
   : 2012-04-07 20:46:37 UTC, authentication_id: 1751951491,
content_id: 3368827987931269>

--------- LOG identity_map_enabled: false --------------------

17 [0408 12:37:53(3092)DEBUG] list: [1751951491]
 18 [0408 12:37:53(3092)DEBUG] MONGODB
weibofav_development['system.namespaces'].find({})
 19 [0408 12:37:53(3092)DEBUG] MONGODB
weibofav_development['favorites'].find({:authentication_id=>{"$in"=>[1751951491]}}).limit(20).sort([[:collected_at, :desc]])
 20 [0408 12:37:53(3092)DEBUG] #<Favorite _id:
4f80c04953cd210b56000003, _type: nil, created_at: 2012-04-07 22:31:37
UTC, updated_at: 2012-04-07 22:31:37 UTC, collected_at
   : 2012-04-07 20:46:37 UTC, authentication_id: 1751951491,
content_id: 3418929751988429>
 21 [0408 12:37:53(3092)DEBUG] MONGODB
weibofav_development['authentications'].find({:_id=>1751951491}).limit(-1).sort([[:_id, :asc]])
 22 [0408 12:37:53(3092)DEBUG] name: magazine
 23 [0408 12:37:53(3092)DEBUG] MONGODB
weibofav_development['favorites'].find({:authentication_id=>{"$in"=>[1751951491]}}).limit(-1).sort([[:collected_at, :desc]])
 24 [0408 12:37:53(3092)DEBUG] MONGODB
weibofav_development['authentications'].find({:_id=>1751951491}).limit(-1).sort([[:_id, :asc]])
 25 [0408 12:37:53(3092)DEBUG] before name: magazine
 26 [0408 12:37:53(3092)DEBUG] MONGODB
weibofav_development['favorites'].find({:authentication_id=>{"$in"=>[1751951491]}}).limit(-1).sort([[:collected_at, :desc]])
 27 [0408 12:37:53(3092)DEBUG] MONGODB
weibofav_development['authentications'].find({:_id=>1751951491}).limit(-1).sort([[:_id, :asc]])
 28 [0408 12:37:53(3092)DEBUG] after query name: magazine
 29 [0408 12:37:53(3092)DEBUG] MONGODB
weibofav_development['favorites'].find({:authentication_id=>{"$in"=>[1751951491]}}).limit(-1).sort([[:collected_at, :desc]])
 30 [0408 12:37:53(3092)DEBUG] MONGODB
weibofav_development['authentications'].find({:_id=>1751951491}).limit(-1).sort([[:_id, :asc]])
 31 [0408 12:37:53(3092)DEBUG] after logger name: magazine
 32 [0408 12:37:53(3092)DEBUG] #<Favorite _id:
4f80c04953cd210b56000005, _type: nil, created_at: 2012-04-07 22:31:37
UTC, updated_at: 2012-04-07 22:31:37 UTC, collected_at
   : 2012-04-07 20:46:37 UTC, authentication_id: 1751951491,
content_id: 3418840442279122>
 33 [0408 12:37:53(3092)DEBUG] MONGODB
weibofav_development['authentications'].find({:_id=>1751951491}).limit(-1).sort([[:_id, :asc]])
 34 [0408 12:37:53(3092)DEBUG] name: magazine
 35 [0408 12:37:53(3092)DEBUG] MONGODB
weibofav_development['favorites'].find({:authentication_id=>{"$in"=>[1751951491]}}).limit(-1).sort([[:collected_at, :desc]])
 36 [0408 12:37:53(3092)DEBUG] MONGODB
weibofav_development['authentications'].find({:_id=>1751951491}).limit(-1).sort([[:_id, :asc]])
 37 [0408 12:37:53(3092)DEBUG] before name: magazine
 38 [0408 12:37:53(3092)DEBUG] MONGODB
weibofav_development['favorites'].find({:authentication_id=>{"$in"=>[1751951491]}}).limit(-1).sort([[:collected_at, :desc]])
 39 [0408 12:37:53(3092)DEBUG] MONGODB
weibofav_development['authentications'].find({:_id=>1751951491}).limit(-1).sort([[:_id, :asc]])
 40 [0408 12:37:53(3092)DEBUG] after query name: magazine
 41 [0408 12:37:53(3092)DEBUG] MONGODB
weibofav_development['favorites'].find({:authentication_id=>{"$in"=>[1751951491]}}).limit(-1).sort([[:collected_at, :desc]])
 42 [0408 12:37:53(3092)DEBUG] MONGODB
weibofav_development['authentications'].find({:_id=>1751951491}).limit(-1).sort([[:_id, :asc]])
 43 [0408 12:37:53(3092)DEBUG] after logger name: magazine
1

There are 1 answers

0
Gary Murakami On

Rails 3.2.1, Mongoid 2.4.8, MongoDB 2.0.4

I replicated your code, except that I do not have Service::Weibo::Api::Oauth nor a working Weibo account to attempt testing that aspect. However, I have the following results and notes that I hope will help.

The authentication_id and content_id are Mongoid generated reference relations that are of type BSON::ObjectId which have a hex identifier string. In your debug code and log, (incorrect) fixnums are shown, so you may want to check this and make sure that your queries are correct.

The following works for me, with results as expected, no nil fields except the ones except for _type, without modifying identity_map. You probably should suspect not using proper BSON::ObjectId's or your Weibo code. Hope that this helps.

-Gary

list = [1751951491]
Rails.logger.debug "list.first: #{list.first}"
auth = Authentication.create(uid: list.first, name: 'authenication name')
content = Content.create(text: 'content text')
favorite = Favorite.new
auth.favorites << favorite
Rails.logger.debug "auth.favorites:#{auth.favorites.inspect}"
assert_equal(1, auth.favorites.length)
content.favorites << favorite
Rails.logger.debug "content.favorites:#{content.favorites.inspect}"
assert_equal(1, content.favorites.length)
auth_list = [auth._id.to_s]
Rails.logger.debug "auth_list:#{auth_list.inspect}"
@favorites = Favorite.any_in(authentication_id: auth_list).to_a
assert_equal(1, @favorites.length)
Rails.logger.debug "@favorites:#{@favorites.inspect}"
@favorites = Favorite.any_in(authentication_id: auth_list).includes(:content, :authentication).desc(:collected_at).to_a
assert_equal(1, @favorites.length)
Rails.logger.debug "@favorites:#{@favorites.inspect}"
@favorites.each do |f|
  Rails.logger.debug f.inspect
  Rails.logger.debug f.authentication.inspect
  Rails.logger.debug f.content.inspect
end