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

Using only with embedded documents automatically saves document

    XMLWordPrintable

    Details

    • Type: Task
    • Status: Closed
    • Resolution: Done
    • Affects Version/s: None
    • Fix Version/s: 4.0.0 final
    • Component/s: None

      Description

      I have a document that has many embedded documents. I thought it would be faster if when I displayed certain values from the document that I use "only" to limit the attributes retrieved. I noticed that if I excluded the embedded document when using only, the document would automatically be saved when I fetched the parent document. ActiveRecord marks documents as readonly and raises an exception if you try to write to a record that has limited attributes retrieved when using select.

      I find this behavior very problematic with Mongoid because it deters the use of larger/complex embedded documents if you can not retrieve specific attributes from a document without having the document automatically updated with default values after retrieval.

      I wrote a spec to illustrate what I am talking about.

      require 'spec_helper'

      class MyDoc
      include Mongoid::Document

      field :field_1
      field :field_2, :default => 'foo'

      embeds_one :embedded_doc

      after_initialize :set_default_values

      def set_default_values

      1. It appears that this is the culprit.
      2. For some reason it seems that the document is being saved after the next assignment
        self.embedded_doc ||= EmbeddedDoc.new
        end

      end

      class EmbeddedDoc
      include Mongoid::Document

      embedded_in :my_doc
      field :field_1, :default => 'Bogus'
      end

      describe MyDoc do

      describe "selecting specific fields" do

      1. The following spec fails because the embedded document is automatically updated
        it "should result in a readonly record" do
        doc = MyDoc.create(field_1: 'text_1', field_2: 'Correct')
        doc.embedded_doc.field_1.should == 'Bogus'
        doc.embedded_doc.field_1 = 'Howdy'
        doc.save
        MyDoc.first.embedded_doc.field_1.should == 'Howdy'
        MyDoc.count.should == 1
        Rails.logger.debug " – Retrieving specific fields"
        MyDoc.only(:field_1).first
        Rails.logger.debug " – Finished retrieving"
        MyDoc.first.field_2.should == 'Correct'
      2. Now notice that the document has been automatically saved
        MyDoc.first.embedded_doc.field_1.should == 'Howdy' # this recieves 'Bogus' and fails
        end

      end

      end

      This is what the log message shows between those two logger statements:

      – Retrieving specific fields
      MONGODB hub_test['my_docs'].find({}, {:_type=>1, :field_1=>1}).limit(-1).sort([[:_id, :asc]])
      MONGODB hub_test['my_docs'].update(

      {"_id"=>BSON::ObjectId('4f8720cd4820683c56000004')}

      , {"$set"=>{"embedded_doc"=>

      {"field_1"=>"Bogus", "_id"=>BSON::ObjectId('4f8720cd4820683c56000006')}

      }})
      – Finished retrieving

      Notice that the document is automatically saved when I call MyDoc.only(:field_1).first

        Attachments

          Activity

            People

            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: