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

Incrementing values in deep embedded documents does not persist

    • Type: Icon: Task Task
    • Resolution: Done
    • Priority: Icon: Blocker - P1 Blocker - P1
    • 5.0.1
    • Affects Version/s: None
    • Component/s: None
    • None

      All started with hunting a bug on mongoid_orderable (https://github.com/pyromaniac/mongoid_orderable/issues/24). Trying to reproduce the steps with a simple update leads me to the conclusion that there must be some trouble with mongoid.

      The following test demonstrates the problem:

      class Survey
        include Mongoid::Document
        embeds_many :questions
        accepts_nested_attributes_for :questions, reject_if: ->(a){ a[:content].blank? }, allow_destroy: true
      end
      
      class Question
        include Mongoid::Document
        field :content
        embedded_in :survey
        embeds_many :answers
      
        accepts_nested_attributes_for :answers, reject_if: ->(a){ a[:content].blank? }, allow_destroy: true
      end
      
      class Answer
        include Mongoid::Document
        embedded_in :question
      
        field :position, type: Integer
      end
      

      spec/mongoid/persistable/incrementable_spec.rb ...

         context "when the document is embedded in another embedded document" do
            shared_examples_for "an incrementable embedded document in another embedded document" do
      
              it "increments a positive value" do
                expect(second_answer.position).to eq(2)
              end
      
              it "persists a positive inc" do
                expect(second_answer.reload.position).to eq(2)
              end
      
              it "clears out dirty changes" do
                expect(second_answer).to_not be_changed
              end
            end
      
            let(:survey) do
              Survey.create
            end
      
            let(:question) do
              survey.questions.create(content: 'foo')
            end
      
            let!(:first_answer) do
              question.answers.create(position: 99)
            end
            
            let!(:second_answer) do
              question.answers.create(position: 1)
            end
      
            context "when providing string fields" do
      
              let!(:inc) do
                second_answer.inc("position" => 1)
              end
      
              it_behaves_like "an incrementable embedded document in another embedded document"
              
            end
      
            context "when providing symbol fields" do
      
              let!(:inc) do
                second_answer.inc(position: 1)
              end
      
              it_behaves_like "an incrementable embedded document in another embedded document"
            end
          end
      
      

      The answer is deeply embedded in survey via question. In the question I create two answers with different positions. Now I would incremente the second answer by one but get the following:

      {
          _id: ObjectId("5356359f646863bfe6000000"),
          questions: [
              {
                  _id: ObjectId("5356359f646863bfe6010000"),
                  content: "foo",
                  answers: [
                      {
                          _id: ObjectId("5356359f646863bfe6020000"),
                          position: 100
                      },
                      {
                          _id: ObjectId("5356359f646863bfe6030000"),
                          position: 1
                      }
                  ]
              }
          ]
      }
      

      Obviously it increments the first object from 99 to 100 but it should increment the second object from 1 to 2 as you can see here:

      {
          _id: ObjectId("5356359f646863bfe6000000"),
          questions: [
              {
                  _id: ObjectId("5356359f646863bfe6010000"),
                  content: "foo",
                  answers: [
                      {
                          _id: ObjectId("5356359f646863bfe6020000"),
                          position: 99
                      },
                      {
                          _id: ObjectId("5356359f646863bfe6030000"),
                          position: 2
                      }
                  ]
              }
          ]
      }
      

      So I call this a bug. Or is there some limitations I didn’t get?

      All is documented as well here: https://github.com/gurix/mongoid/compare/deep_increment

            Assignee:
            emily.stolfo Emily Stolfo
            Reporter:
            gurix Markus Graf
            Votes:
            1 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: