2011-03-09 9 views
5

Tengo un documento mongomapper con documentos incrustados, y quiero hacer una copia de él.Mongomapper: copiar un documento en un documento nuevo

En esencia, lo que estoy tratando de hacer es algo como esto:

customer = Customer.find(params[:id]) 
new_customer = Customer.new 
new_customer = customer 
new_customer.save 

por lo que quiero terminar con dos documentos MongoMapper diferentes, pero con idéntico contenido.

¿Alguna idea de cómo se debe hacer esto?

+0

De un poco de lectura que he hecho, supongo que la única manera de hacerlo es colocar a través de los documentos incrustados en el documento principal, conseguir su atributos, cree nuevos documentos copiando estos atributos para cada uno, hasta que tenga una copia del documento. ¿Alguien puede pensar de otra manera? – futureshocked

Respuesta

4

Para lograr esto, debe cambiar el _id. Se supone que los documentos con el mismo _id son el mismo documento, por lo que al guardar un documento con un _id diferente se creará un documento nuevo.

customer = Customer.find(params[:id]) 
customer._id = BSON::ObjectId.new # Change _id to make a new record 
    # NOTE: customer will now persist as a new document like the new_document 
    # described in the question. 
customer.save # Save the new object 

Como acotación al margen, me inclinaría a almacenar el viejo _id algún lugar en el nuevo registro para poder mantener un registro de quién derivado de quién, pero no es necesario.

+0

Bien, puedo ver cómo puedo combinar tu creación de nuevos identificadores con la forma en que trato los documentos integrados, es decir, doy nuevas copias del documento y sus documentos incorporados a sus nuevas identificaciones. – futureshocked

0

No creo que sea posible (o válido) crear copias de un documento existente en mongodb/mongomapper porque me parece que habría un choque entre el documento/documentos incrustados y sus identificaciones del original y documentos copiados.

Así que resolví mi problema copiando el contenido de los documentos en documentos nuevos, en lugar de los documentos en sí. Este es un ejemplo:

inspection = Inspection.find(params[:inspection_id]) #old document 
new_inspection = Inspection.create     #new target document 
items = inspection.items        #get the embedded documents from inspection 

items.each do |item|         #iterate through embedded documents 
    new_item = Item.create       #create a new embedded document in which 
                 # to copy the contents of the old embedded document 
    new_item.area_comment = item.area_comment   #Copy contents of old doc into new doc 
    new_item.area_name = item.area_name 
    new_item.area_status = item.area_status 
    new_item.clean = item.clean 
    new_item.save          #Save new document, it now has the data of the original 
    new_inspection.items << new_item     #Embed the new document into its parent 
    end 

new_inspection.save         #Save the new document, its data are a copy of the data in the original document 

En realidad, esto funcionó muy bien en mi escenario. Pero tengo curiosidad si las personas tienen una solución diferente.

4

Usted simplemente debe ser capaz de hacer esto:

duplicate_doc = doc.clone 
duplicate_doc.save 
Cuestiones relacionadas