2

I made the early novice-mongodb mistake awhile back and make a lot of has_many relations when I should have been embedding them.

My question is how can I now convert my records from a polymorphic has_many scenario to embeds_many?

#Place.rb
has_many :images, as: :imageable, dependent: :destroy, autosave: true

#Image.rb
belongs_to :imageable, polymorphic: true

to =>

#Place.rb
embeds_many :images, as: :imageable

#Image.rb
embedded_in :imageable, polymorphic: true

I would normally iterate thru all the records and do it that way but I imagine the naming is gonna be a problem. So i'm not sure how I can accomplish this short of creating a temporary model, but I'm hoping a few others have made the same mistake and possibly have a gentle solution?

ere
  • 1,739
  • 3
  • 19
  • 41

1 Answers1

1

For anyone like me, see this question in future!

You can do this by changing your models from has_many to embeds_many (in ruby base code), then use this javascript I wrote for myself:

// Parent is parent model name without 's' and model is related model name without 's',
// if you have something with plural name this function don't work
// example : ref2em('user', 'post')
var ref2em = function(parent, model) {
  var query, update;
  // Search through all instances
  db[parent+'s'].find().forEach(function(ref) {
    query = {};
    // Get all related models with parent_id
    query[parent+"_id"] = ref._id;
    db[model+'s'].find(query).forEach(function(em) {
      // Update parent with $push operator (add model to parent's models attribute)
      update = { $push: {} };
      update['$push'][model+'s'] = em;
      db[parent+'s'].update({_id: ref._id}, update);
    });
  });
}

and then use something like this (to update user has_many posts to user embeds_many posts):

ref2em('user', 'post')

(All this functions just work in mongo console, please make sure you have a backup and you know what you're doing, read comments I wrote and at the end drop old collections).

No warranty, I'm just sharing what I've done (maybe not work for you).

mu is too short
  • 426,620
  • 70
  • 833
  • 800
KiT O
  • 867
  • 6
  • 21