2011-03-09 10 views
5

Mam dokument mongomapper z osadzonymi dokumentami i chcę go skopiować.Mongomapper: skopiuj dokument do nowego dokumentu

W istocie, co próbuję zrobić, to coś takiego:

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

Więc chcę skończyć z dwóch różnych dokumentów mongomapper, ale o identycznej treści.

Jakieś pomysły, jak to zrobić?

+0

Od małego czytania robiłem, mogę zrozumieć, że jedynym sposobem, aby to zrobić jest pętli dokumentów osadzonych w dokumencie macierzystym, uzyskać ich atrybuty, twórz nowe dokumenty, kopiując te atrybuty dla każdego, aż otrzymam kopię dokumentu. Czy ktoś może wymyślić inny sposób? – futureshocked

Odpowiedz

4

Aby to zrobić, musisz zmienić _id. Dokumenty o tym samym numerze _id są uważane za te same dokumenty, więc zapisanie dokumentu z innym numerem _id spowoduje utworzenie nowego dokumentu.

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 

Tak na marginesie, byłbym skłonny do przechowywania starych _id gdzieś w nowej płyty, więc mogłem śledzić, kto pochodzi z kto, ale to nie jest konieczne.

+0

Dobrze, widzę, jak mogę łączyć tworzenie nowych identyfikatorów z tym, jak radzę sobie z dokumentami osadzonymi, tj. Nowe kopie dokumentu i jego dokumentów osadzonych to nowe identyfikatory. – futureshocked

0

Nie sądzę, że jest możliwe (lub ważne) tworzenie kopii istniejącego dokumentu w mongodb/mongomapper, ponieważ wydaje mi się, że wystąpi konflikt dokumentu/dokumentów osadzonych i ich identyfikatorów oryginału i skopiowane dokumenty.

Rozwiązałem więc mój problem, kopiując zawartość dokumentów do nowych dokumentów, a nie samych dokumentów. Oto przykład:

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 

To faktycznie zadziałało bardzo dobrze w moim scenariuszu. Ale jestem ciekawy, czy ludzie mają inne rozwiązanie.

4

Trzeba po prostu być w stanie to zrobić:

duplicate_doc = doc.clone 
duplicate_doc.save 
Powiązane problemy