Setting an embeds_many association to empty array using assign_attributes will actually persist it

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Unknown
    • None
    • Affects Version/s: None
    • Component/s: None
    • None
    • Ruby Drivers
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?
    • None
    • None
    • None
    • None
    • None
    • None

      After upgrading from v7.5.4 to v8.0.10, I noticed that assign_attributes will accidentally write to the database when it's an empty array, seems to be introduced by this https://jira.mongodb.org/browse/MONGOID-4869

      #!/usr/bin/env ruby
      
      require 'logger'
      require 'bundler/inline'
      
      gemfile do
        source 'https://rubygems.org'
        gem "mongoid", "#{ENV["MONGOID_VERSION"] || '8.0.10'}"
        gem "debug", "~> 1.7"
        gem "minitest", require: "minitest/autorun"
      end
      
      require 'mongoid'
      
      Mongoid.configure { |c| c.clients.default = { hosts: ['localhost'], database: 'test' } }
      puts Mongoid::VERSION
      
      class Address
        include Mongoid::Document
        field :city, type: String
        embedded_in :person
      end
      
      class Person
        include Mongoid::Document
        field :name, type: String
        embeds_many :addresses
      end
      
      Person.delete_all
      Address.delete_all
      
      alice = Person.create(name: "Alice")
      alice.addresses = []
      alice.save
      alice.reload
      puts alice.attributes.inspect # {"_id"=>BSON::ObjectId('68b868bdfff9e32aa75132f9'), "name"=>"Alice", "addresses"=>[]}
      
      # Assign attributes with empty addresses get persisted, expect to not persist
      bob = Person.create(name: "Bob")
      bob.assign_attributes(addresses: [])
      puts bob.attributes.inspect # {"_id"=>BSON::ObjectId('68b868bdfff9e32aa75132fa'), "name"=>"Bob"}
      bob.reload
      puts bob.attributes.inspect # {"_id"=>BSON::ObjectId('68b868bdfff9e32aa75132fa'), "name"=>"Bob", "addresses"=>[]}
      
      # Assign attributes with non-empty addresses will not persist as expected
      bob = Person.create(name: "Bob")
      bob.assign_attributes(addresses: [Address.new(city: "New York")])
      puts bob.attributes.inspect # {"_id"=>BSON::ObjectId('68b8697ca91a01bedad64928'), "name"=>"Bob", "addresses"=>[{"_id"=>BSON::ObjectId('68b8697ca91a01bedad64929'), "city"=>"New York"}]}
      bob.reload
      puts bob.attributes.inspect # {"_id"=>BSON::ObjectId('68b8697ca91a01bedad64928'), "name"=>"Bob"}
      

            Assignee:
            Jamis Buck
            Reporter:
            Joe Lim
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated: