Uploaded image for project: 'Mongoid'
  1. Mongoid
  2. MONGOID-2877

identity map doesn't work with has_many association and inheritance

    XMLWordPrintable

    Details

    • Type: Task
    • Status: Closed
    • Resolution: Done
    • Affects Version/s: None
    • Fix Version/s: 3.1.3
    • Component/s: None
    • Labels:
      None

      Description

      Environment
      mongodb 2.2.3
      mongoid 3.1.2
      ruby 1.9.3

      Structure

      class Event
        has_many :children, inverse_of: :parent, class_name: "Event", order: {sequence: 1}
        belongs_to :parent, inverse_of: :children, class_name: "Event", index: true
       
        field :name, type: String
      end
      class Activity < Event
      class Branch < Event
      # There are some other sub-classes of this Event class similar to Activity and Branch.
      

      Now i want to load all events with the given name and eager load their children.

      The query is

      Event.where(name: 'test').includes(:children).each do |event|
         puts event.children.all.flatten
      end
      

      I see the following queries in the moped debug output

      database=uat collection=events selector={"name"=>"test"} flags=[] limit=0 skip=0 batch_size=nil fields=nil
      database=uat collection=events selector={"parent_id"=>{"$in"=>["7723d05b-d866-4153-bda4-48bcc20d7071"]}} flags=[] limit=0 skip=0 batch_size=nil fields=nil
       
      Till now, it makes complete sense, but then mongoid runs one more query to fetch the children again
      database=uat collection=events selector={"parent_id"=>{"$in"=>["7723d05b-d866-4153-bda4-48bcc20d7071"]}} flags=[] limit=0 skip=0 batch_size=nil fields=nil
      

      I guarantee that identity map is enabled in my environment (the following steps would confirm).

      So i jumped into the MONGOID gem and added a bunch of print statements to debug this. I found the difference was in these two methods IdentityMap.set_many and IdentityMap.get_many.

      Inside set_many
      In particular, when mongoid puts the information in identity map, the selector looks like this
      {:_type=>

      {\"$in\"=>[\"Activity\", \"Branch\", \"Event\"]}

      , \"parent_id\"=>\"7723d05b-d866-4153-bda4-48bcc20d7071\"}"
      If you see closely, the selector includes the type array.

      Inside get_many
      However, when mongoid tries to fetch the data from the identity map, the identifier looks like this

      {\"parent_id\"=>\"7723d05b-d866-4153-bda4-48bcc20d7071\"}

      "

      The type field is not included in the search and hence Identity map returns nil. I am not sure how to fix this but any help would be very useful.

      Thank you,
      Naren

        Attachments

          Activity

            People

            Assignee:
            durran Durran Jordan
            Reporter:
            nchainani nchainani
            Participants:
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved: