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

`remove_attribute` on not persisted embedded documents

    XMLWordPrintable

    Details

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

      Description

      I found an issue with remove_attribute called on newly created embedded documents. Seems like mongoid doesn't notice it's a new document and generates an $unset command, but completely messes the path to the document (since it doesn't have a position in an array of children yet). If the child document was persisted it would generate {{"$unset"=>

      {"child_documents.X.flag"=>true}

      }} command, where X would be the position of updated child document. On a new document it generates {{"$unset"=>

      {"child_documents.flag"=>true}}} command and MongoDB silently rejects the whole update operation along with any other changes that were included.

      I think remove_attribute should check new_document? before generating $unset operation.

      Here's a script to replicate the bug:

       
      #!/usr/bin/env ruby
       
      require 'mongoid'
       
      Mongoid.configure do |config|
        config.connect_to "mongoid_test"
      end
       
      Moped.logger = Logger.new(STDOUT)
       
      class RootDocument
        include Mongoid::Document
        embeds_many :child_documents
      end
       
      class ChildDocument
        include Mongoid::Document
        embedded_in :root_document
        field :flag, type: Boolean
      end
       
      RootDocument.delete_all
      parent = RootDocument.create
      child1 = parent.child_documents.build
      child1.flag = true
      parent.save!
       
      puts "Root document: " + RootDocument.first.as_json.inspect
       
      child2 = parent.child_documents.build
      child2.remove_attribute :flag
      parent.save! # this update is silently rejected by MongoDB
       
      puts "Root document: " + RootDocument.first.as_json.inspect
      



      And here's the output with some lines removed for clarity:

       


      MOPED: 127.0.0.1:27017 INSERT database=mongoid_test collection=root_documents documents=[{"_id"=>"513ab4b066d9f181f0000001"}] flags=[] (0.1130ms)
      MOPED: 127.0.0.1:27017 UPDATE database=mongoid_test collection=root_documents selector={"_id"=>"513ab4b066d9f181f0000001"} update={"$pushAll"=>{"child_documents"=>[{"_id"=>"513ab4b066d9f181f0000002", "flag"=>true}]}} flags=[] (0.1299ms)
      Root document: {"_id"=>"513ab4b066d9f181f0000001", "child_documents"=>[{"_id"=>"513ab4b066d9f181f0000002", "flag"=>true}]
      }
      MOPED: 127.0.0.1:27017 UPDATE database=mongoid_test collection=root_documents selector={"_id"=>"513ab4b066d9f181f0000001"} update={"$unset"=>{"child_documents.flag"=>true}

      , "$pushAll"=>{"child_documents"=>[

      {"_id"=>"513ab4b066d9f181f0000003"}

      ]}} flags=[] (0.0951ms)
      Root document: {"_id"=>"513ab4b066d9f181f0000001", "child_documents"=>[

      {"_id"=>"513ab4b066d9f181f0000002", "flag"=>true}

      ]}

       

        Attachments

          Activity

            People

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

              Dates

              • Created:
                Updated:
                Resolved: