0

I'm having trouble saving the correct nested embedded document with mongoid. I've tried this in both v3.1.6 and v4.0.0 and the result is the same. The parent document is saved, but the nested document I modified ignores the changes, and instead updates the first nested document instead.

Assume some models like so:

Mongoid.configure do |config|
  config.sessions = {default: {hosts: ["localhost:27017"], database: "test_mongoid"}}
end

class Band
  include Mongoid::Document

  field :name, type: String
  embeds_many :members
end

class Member
  include Mongoid::Document
  embedded_in :band

  field :name, type: String
  embeds_many :instruments
end

class Instrument
  include Mongoid::Document
  embedded_in :member

  field :name, type: String

  def make_badass!
    self.name = "Badass #{self.name}"
    self.save
  end
end

And a program that runs:

Band.destroy_all

a_band = {
  name: "The Beatles",
  members: [
    {
      name: 'Paul',
      instruments: [
        {
          name: 'Bass guitar'
        },
        {
          name: 'Voice'
        }
      ]
    }
  ]
}
Band.create(a_band)


the_beatles = Band.first

puts the_beatles.as_document

paul = the_beatles.members.first
voice = paul.instruments.where({name: "Voice"}).first

voice.make_badass!

puts Band.first.as_json

The database should now contain:

{
    "_id": ObjectId('53aa7d966d6172889c000000'),
    "name" : "The Beatles",
    "members" : [
        {
            "_id" : ObjectId('53aa7d966d6172889c010000'),
            "name" : "Paul",
            "instruments" : [
                {"_id" : ObjectId('53aa7d966d6172889c020000'), "name" : "Bass guitar"},
                {"_id" : ObjectId('53aa7d966d6172889c030000'), "name" : "Voice"}
            ]
        }
    ]
}

But instead, it contains:

{
    "_id": ObjectId('53aa7d966d6172889c000000'),
    "name" : "The Beatles",
    "members" : [
        {
            "_id" : ObjectId('53aa7d966d6172889c010000'),
            "name" : "Paul",
            "instruments" : [
                {"_id" : ObjectId('53aa7d966d6172889c020000'), "name" : "Badass Voice"},
                {"_id" : ObjectId('53aa7d966d6172889c030000'), "name" : "Voice"}
            ]
        }
    ]
}

What would be a working way of having the correct embedded document to change from within the instance method of Instrument?

Thanks for your help!

Roberto
  • 1,944
  • 1
  • 30
  • 42

1 Answers1

0

Mongoid is quickly forcing me to become an alcoholic. Hopefully it will help someone in the same situation.

class Instrument
  include Mongoid::Document
  embedded_in :member

  field :name, type: String

  def make_badass
    self.name = "Badass #{self.name}"
    self.member.band.save
  end

  def unset_name
    # self.unset :name does not work
    self.remove_attribute :name
    self.member.band.save
  end

end
Roberto
  • 1,944
  • 1
  • 30
  • 42