Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoid: convert embedded document into referenced/own collection

I need to convert an embedded document onto its own collection, so it can be referenced from another collection.

Lets suppose I have a Parent that embeds many Childs. I was thinking of something along this:

Parent.all.each do |p|
 p.childs.all.each do |c|
  c.raw_attributes['parent_id'] = p.id
 end
 p.save! #will save parent and cascade persist all childs onto their own coll
end

Is this an option? Ideally I would run this in a console and I would only change mongoid mappings from embed_* to has_*, so I wouldn't need to change the rest of my code or use another collection as staging.

like image 673
Miguel Ping Avatar asked Mar 16 '12 00:03

Miguel Ping


Video Answer


2 Answers

too little rep to comment, but I think Sergio's (otherwise very helpful) answer may be outdated. With mongoid 3.0.5 I couldn't use

child_coll = Mongoid.database.collection('children')

but instead used

child_coll = Mongoid.default_session[:children]

which did the trick for me

like image 66
sbauch Avatar answered Sep 22 '22 08:09

sbauch


Here is an updated version of Sergio Tulentsev's approach with Pencilcheck's addition and an update of sbauch's correction.

First, leave the embeds_many/embedded_in statements in place in your models.

Second, run something like this block of code:

child_coll =  Mongoid.client(:default).database.collection(:children)
Parent.all.each do |p|
  p.childs.all.each do |c|
    dup = c.attributes
    dup['_id'] = nil
    dup['parent_id'] = p.id
    child_coll.insert_one dup # save children to separate collection
    c.destroy
  end
  p.childs = nil # remove embedded data
  p.save
end

Third, change your embeds_many to has_many and your embedded_in to belongs_to.

Fini.

like image 27
Chip Roberson Avatar answered Sep 24 '22 08:09

Chip Roberson