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

nested embeds_many doesn't work

    XMLWordPrintable

    Details

    • Type: Task
    • Status: Closed
    • Priority: Major - P3
    • Resolution: Gone away
    • Affects Version/s: None
    • Fix Version/s: 5.0.1
    • Component/s: None
    • Labels:
      None

      Description

      We have

          class User
            include Mongoid::Document
            # some fields
            embeds_many :conversations
            accepts_nested_attribute_for :conversations
          end
          class Conversation
            include Mongoid::Document
            # some fields
            embedded_in :user
            embeds_many :messages
            accepts_nested_attribute_for :messages
          end
          class Message
            include Mongoid::Document
            field :message, type: String
            # some fields
            embedded_in :conversation
          end
      

      Now we create a user that has 2 conversations each with 2 messages

          u = User.create!
          c1 = u.conversations.create!
          c1.messages.create!(message: "one")
          c1.messages.create!(message: "two")
          c2 = u.conversations.create!
          c2.messages.create!(message: "three")
          c2.messages.create!(message: "four")
      

      Then, we need to change the message "two" with "six",

        
          u = User.last
          c1 = u.conversations.first
          m2 = c1.messages.last
          m2.message = "six"
          m2.save!
          m2.valid? # => true
      

      After all of this, why is it that it is not message "two" that is updated to "six", instead, it is "one" that now becomes "six" and "two" remains as "two"

      I noticed that the update part of the code produces this following Moped update query :

      selector={"_id"=>BSON::ObjectId('539e4ec04db79b997d00000c'), "conversations._id"=>BSON::ObjectId('539e6c254db79b84ab00000d'), "conversatoins.0.messages._id"=>BSON::ObjectId('539fac734db79b1e4100000f')} update={"$set"=>{"conversations.0.messages.$.message"=>"six"}}
      

      I have tried to translate this MOPED syntax to javascript and tested it in mongo shell, that produced the same behavior. Then I realized that in MongoDB, positional operator "$" cannot be used to locate inner array.

      The question is, if Core MongoDB does not serve locating inner array element index using "$" (positional operator), why does Mongoid produce this query on nested embeds_many (nested MongoDB arrays)? Why not just makes a class that has embeds_many and embedded_in at the same time as invalid?

      Note: To test this I used Mongoid 4.0.0 rc1 and for the mongo shell, the version is 2.6.2

        Attachments

          Issue Links

            Activity

              People

              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: