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

Duplicate instances in relations target after using #find

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

      When running #find on a one-to-many relation, the relation's target is appended with a duplicate instance of the found document. #to_a then returns an array with the extra object.

      This only happens after #each is called with a block on the relation.

      This behavior is present in both Mongoid 3 and 4.

      Please let me know if you need more info. Hope this helps! :smile_cat:

       ruby
      require 'mongoid' # v4.0.2
      
      Mongoid::Config.load_configuration({
        sessions: {
          default: {
            database: 'db',
            hosts: ['localhost:27017']
          }
        }
      })
      
      class Person
        include Mongoid::Document
        has_many :pets
      end
      
      class Pet
        include Mongoid::Document
        belongs_to :person
      end
      
      RSpec.describe Person do
        let(:person) { Person.create! }
        let(:pet_id) { person.pets.first.id }
      
        before { 5.times { person.pets.create! } }
      
        # This Passes
        specify 'finding a pet should not change the count of pets' do
          expect { person.pets.find(pet_id) }.not_to change { person.pets.count }
        end
      
        # This Fails
        specify 'finding a pet should not change the size of the pets array' do
          expect { person.pets.find(pet_id) }.not_to change { person.pets.to_a.size }
        end
      
        # This Fails
        specify 'finding a pet should not change the count of the pets target' do
          expect { person.pets.find(pet_id) }.not_to change { person.pets.target.count }
        end
      
        # This Passes
        context 'when `#each` was NOT called on the pets relation' do
          specify 'finding a pet should not change the size of the pets array' do
            person.pets.find(pet_id)
            expect(person.pets.count).to eq(person.pets.to_a.size)
          end
        end
      
        # This Fails
        context 'when `#each` WAS called a block on the pets relation' do
          before { person.pets.each {} }
          specify 'finding a pet should not change the size of the pets array' do
            person.pets.find(pet_id)
            expect(person.pets.count).to eq(person.pets.to_a.size)
          end
        end
      end
      

      ping @JKring

            Assignee:
            Unassigned Unassigned
            Reporter:
            tonyta tonyta
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved: