-
Type: Task
-
Resolution: Done
-
Affects Version/s: None
-
Component/s: None
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
- It appears that this is the culprit.
- 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
- 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' - 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(
, {"$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