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

Conflicting or missing modifications when updating using nested attributes

    XMLWordPrintable

    Details

    • Type: Task
    • Status: Closed
    • Priority: Major - P3
    • Resolution: Won't Fix
    • Affects Version/s: None
    • Fix Version/s: 12_01_17
    • Component/s: None
    • Labels:

      Description

      Summary

      Given a root document embedding two or more levels of documents, updating the embedded documents via mass-assignment and nested attributes can cause a conflicting modifications exception or persist the modifications under a blank key.

      Steps to reproduce

      Given the following documents:

      class Train
        include Mongoid::Document
        
        embeds_many :cars
        
        accepts_nested_attributes_for :cars
      end
       
      # A train car
      class Car
        include Mongoid::Document
        
        embedded_in :train
        embeds_many :seats
          
        def capacity=(count)
          self.seats = Array.new(count).map { Seat.new }
        end
      end
       
      class Seat
        include Mongoid::Document
        
        embedded_in :car
      end
      

      Execute:

      t = Train.create!
      t.update_attributes(cars_attributes: [{capacity: 2}])
      

      Expected results

      A train is persisted with one car containing two seats. The document is stored in Mongo as:

      {
      	"_id" : ObjectId("51746559e3defe7883000001"),
      	"cars" : [
      		{
      			"_id" : ObjectId("51746559e3defe7883000002"),
      			"seats" : [
      				{
      					"_id" : ObjectId("51746559e3defe7883000003")
      				},
      				{
      					"_id" : ObjectId("51746559e3defe7883000004")
      				}
      			]
      		}
      	]
      }
      

      Actual results

      If using Mongo 2.0.4 the update will fail with a conflicting-mods error from Mongo. The car and its seats will not be created.

      If using Mongo 2.4.2 the update will appear to succeed. Upon reloading the train, however, it will have no cars and no seats. The document is stored in Mongo as:

      {
      	"" : [
      		{
      			"_id" : ObjectId("51745e08e3defeea70000004"),
      			"seats" : [
      				{
      					"_id" : ObjectId("51745e08e3defeea70000002")
      				},
      				{
      					"_id" : ObjectId("51745e08e3defeea70000003")
      				}
      			]
      		}
      	],
      	"_id" : ObjectId("51745e04e3defeea70000001"),
      	"seats" : [
      		{
      			"_id" : ObjectId("51745e08e3defeea70000002")
      		},
      		{
      			"_id" : ObjectId("51745e08e3defeea70000003")
      		}
      	]
      }
      

      Configuration used

      • Rails 3.2.13
      • Mongoid 3.1.3
      • Safe mode enabled for Mongoid session
      • Mongo 2.0.4 when producing the conflicting-mods behavior
      • Mongo 2.4.2 when producing the missing modifications behavior

      Attachments

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              durran.jordan Durran Jordan
              Reporter:
              evanchaney evanchaney
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: