unset in embedded document array

55 views
Skip to first unread message

Clint

unread,
Aug 22, 2011, 10:28:29 AM8/22/11
to MongoMapper
Hi,

I have a model relation, that looks something like this:

class IcecreamMan
include MongoMapper::Document

one :wagon
end

class Wagon
include MongoMapper::EmbeddedDocument

many :kinds

belongs_to :icecream_man
end

class Kind
include MongoMapper::EmbeddedDocument

key :color, String
key :rating, String
key :taste, String

belongs_to :wagon
end



So, my problem is, that I have to add a new attribute to kind, let's
say sugar_level. On top of that I have to remove the taste attribute.
I trolled the google groups a bit and stumbled upon $unset. But unset
only seems to work for normal Documents, not for EmbeddedDocuments.
Only solution I have found so far, is to copy the old attributes in a
temporary object, destroy the complete array and create a new one.

Can anyone help me to solve this problem with style? Thank you very
much.

Scott Messinger

unread,
Aug 22, 2011, 5:52:17 PM8/22/11
to mongo...@googlegroups.com
I think you should be able to unset a value in a embedded doc from the main doc--just reach into the embedded doc array and unset a value. The mongodb docs would probably be the best place to look as I'm not sure how off the top of my head...but I do think it's possible.

-Scott



--
You received this message because you are subscribed to the Google
Groups "MongoMapper" group.
For more options, visit this group at
http://groups.google.com/group/mongomapper?hl=en?hl=en

Clint

unread,
Aug 23, 2011, 4:40:16 AM8/23/11
to MongoMapper
Thank you for your reply Scott. The problem is, that I have an array
of embedded documents.
Reaching into a normal embedded document is no problem, but an
array ...

I don't think this is solvable with MongoMapper alone, so using raw
MongoDB-Queries is a given.
After trying a lot of different approaches, I stumbled upon this
ticket:
http://groups.google.com/group/mongodb-user/browse_thread/thread/db518cd3dbd3d48f

I will try pulling out the big guns and update when finding a partial
pretty solution.



On Aug 22, 11:52 pm, Scott Messinger <scottmessin...@gmail.com> wrote:
> I think you should be able to unset a value in a embedded doc from the main
> doc--just reach into the embedded doc array and unset a value. The mongodb
> docs would probably be the best place to look as I'm not sure how off the
> top of my head...but I do think it's possible.
>
> -Scott
>

Clint

unread,
Aug 23, 2011, 5:17:02 AM8/23/11
to MongoMapper
Ok, I have an really weird update:
My models are already updated, so they all have a sugar_level
attribute
and no taste anymore...


class Kind
include MongoMapper::EmbeddedDocument
key :color, String
key :rating, String
key :sugar_level, String

belongs_to :wagon
end


The mongoDB still holds the taste attribute for all records.
I tried to clone a kind document and save it in a temp object.
Let us assume the icecreamman only has one "kind".
Code is better than words:

man = IcecreamMan.first
temp = man.wagon.kinds.first.clone
man.wagon.kinds = []
man.save

new_kind = Kind.new(:color => temp.color, :rating =>
temp.rating, :sugar_level => temp.taste) #everything fine so far
man.wagon.kinds <<
new_kind
# new_kind doesn't have a taste attribute
man.save
# valid and saving

man.reload.wagon.kinds.first # taste attribute is back and nil


Everything works fine. When I reload the document, the nasty 'taste'
attribute is back and set to nil.
Kind.new doesn't have a 'taste' attribute. Now I am really stuck.




On Aug 23, 10:40 am, Clint <simon.krollpfei...@gmail.com> wrote:
> Thank you for your reply Scott. The problem is, that I have an array
> of embedded documents.
> Reaching into a normal embedded document is no problem, but an
> array ...
>
> I don't think this is solvable with MongoMapper alone, so using raw
> MongoDB-Queries is a given.
> After trying a lot of different approaches, I stumbled upon this
> ticket:http://groups.google.com/group/mongodb-user/browse_thread/thread/db51...

Clint

unread,
Aug 23, 2011, 7:47:59 AM8/23/11
to MongoMapper
Ok, before I drown myself in beer:

To solve this problem, I had to reload the class entirely, as soon as
the object
is loaded from the database, the class will have the "old" and the
"new" attributes.
In order to solve this, I had to call a crazy:

Object.class_eval do
remove_const :Kind
end
load "kind.rb"

This will reload the class and flush out the old attribute.
1. save values to a temp variable
2. clear old values from the database
3. reload the class
4. write new object to database

Jon Kern

unread,
Aug 23, 2011, 10:01:06 AM8/23/11
to mongo...@googlegroups.com
I don't have the energy to dive deep into your problems, only some (possibly not too helpful) comments:

  1. The symptoms and workarounds smell to me... something might be wrong in the way you are doing things
  2. the domain model (such as it is) also seems very different than i would expect.
    • I just have trouble thinking that a Wagon is an integral component of an Ice Cream Man :-(
    • And "Kinds" describe the kind of ice cream. If anything, a wagon would have amounts of ice cream loaded on the truck, each of which would then reference the kind (and add an amount on hand -- aka inventory)
it is my shortcoming, i know, but i have trouble getting past the example to dig into your real problems.

imo, you should not have to reload a class. ever. you would need to reload an in-memory instance if you changed it (like via an update_attributes) and you want to continue using the instance.
jon

blog: http://technicaldebt.com
twitter: http://twitter.com/JonKernPA

Clint said the following on 8/23/11 7:47 AM:

Dan Gal

unread,
Apr 22, 2015, 1:14:01 AM4/22/15
to mongo...@googlegroups.com
Have you found a solution to this problem? four years later and I am facing the same thing... If you have can you please give a code example?
Reply all
Reply to author
Forward
0 new messages