2012-01-09 15 views
6

कैसे आप के बारे में गहरी एक दस्तावेज़ (mongoid)एम्बेडेड संघों के साथ दीप क्लोन दस्तावेज़

मैं कुछ इस तरह की कोशिश की है क्लोनिंग जाने हैं MongoDB में;

original = Car.find(old_id) 
@car = original.clone 
@car._id = BSON::ObjectId.new 

लेकिन मैं बाद में मूल्यों की समस्याओं अक्रमांकन मिलता है।

_id को छोड़कर मैं सभी दस्तावेज़ विशेषताओं के साथ गहरा क्लोन कैसे बना सकता हूं?

संपादित करें: ज़ैचरी के उदाहरण के बाद मुझे डुप्लीकेट दस्तावेज़ों के लिए कस्टम सीरियलाइजेशन क्लास के साथ कुछ समस्याएं मिलीं।

class OptionHash 
    include Mongoid::Fields::Serializable 

    # Convert the keys from Strings to Symbols 
    def deserialize(object) 
    object.symbolize_keys! 
    end 

    # Convert values into Booleans 
    def serialize(object) 
    object.each do |key, value| 
    object[key] = Boolean::MAPPINGS[value] 
    end 
end 

ऑब्जेक्ट डुप्लिकेट दस्तावेज़ों के लिए शून्य है। Car.find (old_id)। सामग्री वास्तव में कस्टम serialization के साथ फ़ील्ड शामिल नहीं है, वह क्यों है और मैं इसे कैसे शामिल कर सकता हूं?

+0

क्या आप समस्याओं के बारे में अधिक विशिष्ट हो सकते हैं? – Barrie

+0

बाद में आपको क्या समस्याएं हैं? –

+0

मुझे लगता है कि समस्या यह है कि एम्बेडेड दस्तावेज़ की आईडी अद्यतन नहीं होती है। यानी मूल दस्तावेज़ में एम्बेडेड दस्तावेज़ों के आईडी के साथ विवाद। – Yeggeps

उत्तर

7

आपको कॉल करने की आवश्यकता नहीं है। इस पर क्लोन करें, आप attributes से कच्चे डेटा का उपयोग कर सकते हैं। उदाहरण के लिए नीचे दिए गए विधि/उदाहरण पूरे दस्तावेज़ में नए आईडी प्रदान करेंगे यदि यह एक पाता है।

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)) 

और तुम अब कार की एक प्रति है। यह अक्षम है हालांकि रिकॉर्ड के लिए पूरे हैश से गुजरना है कि यह पता लगाने के लिए कि एम्बेडेड दस्तावेज़ में कोई एम्बेडेड दस्तावेज़ हैं या नहीं। आप बेहतर होगा संरचना अपने आप को रीसेट होगा यदि आप जानते हैं कि यह कैसे हो जाएगा, उदाहरण के लिए, यदि आप एक भागों कार में एम्बेडेड है, तो आप सिर्फ कर सकते हैं:

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} 

एक बहुत अधिक की तुलना में कुशल है कौन सा बस एक सामान्य रीसेट कर रहे हैं।

+0

हाय धन्यवाद, सवाल को अद्यतन किया क्योंकि मुझे इस दृष्टिकोण के साथ कुछ समस्याएं मिलीं। – Yeggeps

+0

एचआरएम। मुझे Mongoid :: फ़ील्ड :: Serializable के साथ ज्यादा अनुभव नहीं है। जब आप 'original.attributes' को कॉल करते हैं तो मैं यह देखने के लिए जांच करूंगा कि किस प्रकार का डेटा पारित किया जा रहा है। क्या आपको धारावाहिक डेटा या deserialized डेटा मिल रहा है? यह संभवतः एक deserialized डेटा गुजरने के साथ एक मुद्दा है ताकि आप क्लोनिंग से पहले इसे क्रमबद्ध करने की जरूरत है। –

+0

उत्कृष्ट पोस्ट .. मुझे यह काम करने के लिए केवल rails3 में mass_assignment सुरक्षा के लिए खाता था। मॉडल से attr_accessible को हटाकर यह एक आकर्षण की तरह काम किया .. धन्यवाद! – Tigraine

0

तुम इतनी कोड

def reset_ids(attributes) 
    attributes.each do |key, value| 
     if key == "_id" && value.is_a?(Moped::BSON::ObjectId) 
      attributes[key] = Moped::BSON::ObjectId.new 
     elsif value.is_a?(Hash) || value.is_a?(Array) 
      attributes[key] = reset_ids(value) 
     end   
    end 
    attributes 
end 

car_original = Car.find(id) 
car_copy = Car.instantiate(reset_ids(car_original.attributes)) 
car_copy.insert 

है यह समाधान बहुत साफ नहीं है, लेकिन मैं बेहतर नहीं मिला है यदि आप क्षेत्रों स्थानीयकृत Car.instantiate उपयोग करना होगा।

संबंधित मुद्दे