You do not need to call .clone, you can use the raw data from attributes . For example, the method / example below will give new identifiers in the entire document if it finds it.
def reset_ids(attributes) attributes.each do |key, value| if key == "_id" and value.is_a?(BSON::ObjectId) attributes[key] = BSON::ObjectId.new elsif value.is_a?(Hash) or value.is_a?(Array) attributes[key] = reset_ids(value) end end attributes end original = Car.find(old_id) car_copy = Car.new(reset_ids(original.attributes))
And now you have a copy of the car. This is inefficient, though, since it has to go through the entire hash for writing in order to find out if there are embedded documents in the embedded document. You would be better off resetting the structure yourself if you know how it will be, for example, if you have parts built into the machine, then you can simply do:
original = Car.find(old_id) car_copy = Car.new(original.attributes) car_copy._id = BSON::ObjectId.new car_copy.parts.each {|p| p._id = BSON::ObjectId.new}
This is much more efficient than just creating a reset.
Zachary anker
source share