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

`remove_attribute` on not persisted embedded documents

    • Type: Icon: Task Task
    • Resolution: Done
    • 3.1.3
    • Affects Version/s: None
    • Component/s: None
    • Labels:

      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}

      ]}

      
      

            Assignee:
            durran Durran Jordan
            Reporter:
            amw Adam Wróbel
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved: