-
Type: Task
-
Resolution: Done
-
Priority: Blocker - P1
-
Affects Version/s: None
-
Component/s: None
-
None
Greetings,
Using mongoid(git:38de2e96edc8f64fbe3cdbe062f1d91e9feb388d 2 days ago) I encountered a perplexing problem when trying to save embedded documents. I believe after_initialize prevents the saving of embedded documents. I have the test files located in a git repo for your convenience:
https://github.com/danlo/mongoid_after_init_bug
test.rb
require 'mongoid' require 'pp' Mongoid.load!('mongoid.yml', :test) # the big container object class Book include Mongoid::Document embeds_many :pages end # the smaller embeded_in object class Page include Mongoid::Document embedded_in :book embeds_many :notes field :content, :type => String end # and one more time class Note include Mongoid::Document embedded_in :page field :message, :type => String end # clear previous test cases Book.mongo_session[Book.collection.name].drop # setup the basic object book = Book.new({ :pages => [ { content: "Page 1", notes: [ { message: "Page 1 / Note A" }, { message: "Page 1 / Note B" } ] }, { content: "Page 2", notes: [ { message: "Page 2 / Note A" }, { message: "Page 2 / Note B" } ] } ] }) book.id = '123' book.save puts "---------------- A good copy of the document" pp book.as_document
test2.rb
require 'mongoid' require 'pp' require 'byebug' require 'pry-byebug' Mongoid.load!('mongoid.yml', :test) # the big container object class Book include Mongoid::Document embeds_many :pages end # the smaller embeded_in object class Page include Mongoid::Document embedded_in :book embeds_many :notes field :text, :type => String if true # true, breaks the code; false, allows the code to work. after_initialize do if self[:content] self[:text] = self[:content] self.remove_attribute(:content) end end end end class Note include Mongoid::Document embedded_in :page field :message, :type => String end book = Book.find '123' # we will now remove those notes, and a new "C" note book.pages.each do | page | # going to make sure we actually clear it page.notes.clear page.notes = nil page.notes.destroy_all page.save page.notes.new(message: "Note C") page.save end if ! book.save puts "-------------- Oh noes! We didn't save" end puts "---------------- We have removed all notes from all pages; and added a new 'Note C'; Below is correct" pp book.as_document puts "\n\n---------------- Now reloading the book we see that 'Note C' was never saved" book = Book.find '123' pp book.as_document
sample output
$ bundle exec ruby test.rb ---------------- A good copy of the document {"_id"=>"123", "pages"=> [{"_id"=>"525e0b789f4a1a800c000001", "content"=>"Page 1", "notes"=> [{"_id"=>"525e0b789f4a1a800c000002", "message"=>"Page 1 / Note A"}, {"_id"=>"525e0b789f4a1a800c000003", "message"=>"Page 1 / Note B"}]}, {"_id"=>"525e0b789f4a1a800c000004", "content"=>"Page 2", "notes"=> [{"_id"=>"525e0b789f4a1a800c000005", "message"=>"Page 2 / Note A"}, {"_id"=>"525e0b789f4a1a800c000006", "message"=>"Page 2 / Note B"}]}]} $ bundle exec ruby test2.rb ---------------- We have removed all notes from all pages; and added a new 'Note C'; Below is correct {"_id"=>"123", "pages"=> [{"_id"=>"525e0b789f4a1a800c000001", "notes"=>[{"_id"=>"525e0b7b9f4a1aec2c000001", "message"=>"Note C"}], "text"=>"Page 1"}, {"_id"=>"525e0b789f4a1a800c000004", "notes"=>[{"_id"=>"525e0b7b9f4a1aec2c000002", "message"=>"Note C"}], "text"=>"Page 2"}]} ---------------- Now reloading the book we see that 'Note C' was never saved {"_id"=>"123", "pages"=> [{"_id"=>"525e0b789f4a1a800c000001", "notes"=> [{"_id"=>"525e0b789f4a1a800c000002", "message"=>"Page 1 / Note A"}, {"_id"=>"525e0b789f4a1a800c000003", "message"=>"Page 1 / Note B"}], "text"=>"Page 1"}, {"_id"=>"525e0b789f4a1a800c000004", "notes"=> [{"_id"=>"525e0b789f4a1a800c000005", "message"=>"Page 2 / Note A"}, {"_id"=>"525e0b789f4a1a800c000006", "message"=>"Page 2 / Note B"}], "text"=>"Page 2"}]} $
Thank you for all the hard work you guys are putting into this. I can't wait until 4.0.0 comes out!