-
Type: Task
-
Resolution: Done
-
Priority: Major - P3
-
Affects Version/s: None
-
Component/s: None
-
None
If you try to use has_and_belongs_to_many eager loading with dependent objects having _id field of type BSON::Binary you get empty arrays instead of children. Mongoid does perform a single query to load all these objects, but then doesn't seem to be able to find results and performs additional queries with nil instead of actual children IDs. This seems to be something specific to Binary fields, because IDs of type String work just as well as regular ObjectId type.
Test script:
#gem "mongoid", "=3.1.6" gem "mongoid", "=4.0.0" require "mongoid" puts "Using Mongoid #{Mongoid::VERSION}" Mongoid.configure {|c| c.connect_to "test"} def verbose old_logger = Moped.logger Moped.logger = Logger.new(STDOUT) puts "\n\n" yield ensure Moped.logger = old_logger end class Parent include Mongoid::Document has_and_belongs_to_many :children, inverse_of: nil end class Child include Mongoid::Document field :_id, type: BSON::Binary, default: -> { BSON::Binary.new SecureRandom.hex(3) } field :something, type: Integer, default: -> {rand(1_000)} end Parent.delete_all 3.times do parent = Parent.create 5.times do parent.children << Child.create end end verbose do puts "Without eager loading" Parent.all.each {|p| puts p.children.map(&:something).inspect} end verbose do puts "With eager loading" Parent.all.includes(:children).each {|p| puts p.children.map(&:something).inspect} end
Output:
mongoid-errors$ruby eager_load.rb Using Mongoid 4.0.0 W, [2014-08-24T02:22:12.058385 #95340] WARN -- : Overwriting existing field _id in class Child. Without eager loading D, [2014-08-24T02:22:12.088171 #95340] DEBUG -- : MOPED: 127.0.0.1:27017 QUERY database=test collection=parents selector={} flags=[] limit=0 skip=0 batch_size=nil fields=nil runtime: 0.3770ms D, [2014-08-24T02:22:12.089165 #95340] DEBUG -- : MOPED: 127.0.0.1:27017 QUERY database=test collection=children selector={"$and"=>[{"_id"=>{"$in"=>[#<BSON::Binary:0x007f7f7aa88e90 @data="64d53e", @type=:generic>, #<BSON::Binary:0x007f7f7aa88c88 @data="6ed747", @type=:generic>, #<BSON::Binary:0x007f7f7aa888f0 @data="be81ff", @type=:generic>, #<BSON::Binary:0x007f7f7aa88710 @data="e950c4", @type=:generic>, #<BSON::Binary:0x007f7f7aa88580 @data="7da04e", @type=:generic>]}}]} flags=[] limit=0 skip=0 batch_size=nil fields=nil runtime: 0.4480ms [201, 753, 564, 497, 433] D, [2014-08-24T02:22:12.090226 #95340] DEBUG -- : MOPED: 127.0.0.1:27017 QUERY database=test collection=children selector={"$and"=>[{"_id"=>{"$in"=>[#<BSON::Binary:0x007f7f7aa88008 @data="56fe72", @type=:generic>, #<BSON::Binary:0x007f7f7aa7be98 @data="9a6cdf", @type=:generic>, #<BSON::Binary:0x007f7f7aa7bd58 @data="96956e", @type=:generic>, #<BSON::Binary:0x007f7f7aa7bc40 @data="c8e19d", @type=:generic>, #<BSON::Binary:0x007f7f7aa7ba38 @data="7e7f2e", @type=:generic>]}}]} flags=[] limit=0 skip=0 batch_size=nil fields=nil runtime: 0.4310ms [21, 167, 84, 450, 195] D, [2014-08-24T02:22:12.091216 #95340] DEBUG -- : MOPED: 127.0.0.1:27017 QUERY database=test collection=children selector={"$and"=>[{"_id"=>{"$in"=>[#<BSON::Binary:0x007f7f7aa7b5b0 @data="0b98dd", @type=:generic>, #<BSON::Binary:0x007f7f7aa7b470 @data="32c896", @type=:generic>, #<BSON::Binary:0x007f7f7aa7b358 @data="5b0738", @type=:generic>, #<BSON::Binary:0x007f7f7aa7b218 @data="693c6d", @type=:generic>, #<BSON::Binary:0x007f7f7aa7b060 @data="4d2996", @type=:generic>]}}]} flags=[] limit=0 skip=0 batch_size=nil fields=nil runtime: 0.4080ms [845, 431, 694, 885, 190] With eager loading D, [2014-08-24T02:22:12.092050 #95340] DEBUG -- : MOPED: 127.0.0.1:27017 QUERY database=test collection=parents selector={} flags=[] limit=0 skip=0 batch_size=nil fields=nil runtime: 0.3240ms D, [2014-08-24T02:22:12.093532 #95340] DEBUG -- : MOPED: 127.0.0.1:27017 QUERY database=test collection=children selector={"_id"=>{"$in"=>[#<BSON::Binary:0x007f7f7ab53a78 @data="64d53e", @type=:generic>, #<BSON::Binary:0x007f7f7ab53960 @data="6ed747", @type=:generic>, #<BSON::Binary:0x007f7f7ab53870 @data="be81ff", @type=:generic>, #<BSON::Binary:0x007f7f7ab53730 @data="e950c4", @type=:generic>, #<BSON::Binary:0x007f7f7ab53618 @data="7da04e", @type=:generic>, #<BSON::Binary:0x007f7f7ab53190 @data="56fe72", @type=:generic>, #<BSON::Binary:0x007f7f7ab53050 @data="9a6cdf", @type=:generic>, #<BSON::Binary:0x007f7f7ab52f10 @data="96956e", @type=:generic>, #<BSON::Binary:0x007f7f7ab52e20 @data="c8e19d", @type=:generic>, #<BSON::Binary:0x007f7f7ab52c90 @data="7e7f2e", @type=:generic>, #<BSON::Binary:0x007f7f7ab527e0 @data="0b98dd", @type=:generic>, #<BSON::Binary:0x007f7f7ab526f0 @data="32c896", @type=:generic>, #<BSON::Binary:0x007f7f7ab52600 @data="5b0738", @type=:generic>, #<BSON::Binary:0x007f7f7ab524e8 @data="693c6d", @type=:generic>, #<BSON::Binary:0x007f7f7ab523d0 @data="4d2996", @type=:generic>]}} flags=[] limit=0 skip=0 batch_size=nil fields=nil runtime: 0.6100ms D, [2014-08-24T02:22:12.094905 #95340] DEBUG -- : MOPED: 127.0.0.1:27017 QUERY database=test collection=children selector={"$and"=>[{"_id"=>{"$in"=>[nil, nil, nil, nil, nil]}}]} flags=[] limit=0 skip=0 batch_size=nil fields=nil runtime: 0.3530ms [] D, [2014-08-24T02:22:12.095608 #95340] DEBUG -- : MOPED: 127.0.0.1:27017 QUERY database=test collection=children selector={"$and"=>[{"_id"=>{"$in"=>[nil, nil, nil, nil, nil]}}]} flags=[] limit=0 skip=0 batch_size=nil fields=nil runtime: 0.3270ms [] D, [2014-08-24T02:22:12.096201 #95340] DEBUG -- : MOPED: 127.0.0.1:27017 QUERY database=test collection=children selector={"$and"=>[{"_id"=>{"$in"=>[nil, nil, nil, nil, nil]}}]} flags=[] limit=0 skip=0 batch_size=nil fields=nil runtime: 0.2800ms []