2009-03-27 10 views
17

वहाँ एक मॉडल दूसरे करने के लिए की संघों कॉपी करने के लिए एक तरह सेActiveRecord: क्या मैं एसोसिएशन कॉपी कर सकता हूं?

template_model = MyModel.find(id) 
new_model = template_model.clone 
new_model.children << template_model.children # I want to *copy* children 

इस तरह है ... ... कि मैं नए मॉडल के लिए टेम्पलेट से बच्चों को कॉपी? (वास्तव में यह कोड बच्चों को टेम्पलेट से नए मॉडल में ले जाता है)।

मुझे पता है कि मैं इसे मैन्युअल रूप से लूपिंग कर सकता हूं, लेकिन क्या अधिक संक्षिप्त तरीका है?

धन्यवाद

उत्तर

25

समस्या यह है कि आप टेम्पलेट क्लोनिंग कर रहे हैं, लेकिन क्लोनिंग नहीं यह बच्चों है। कुछ ऐसा प्रयास करें:

template_model = MyModel.find(id) 
new_model = template_model.clone 
new_model.children << template_model.children.collect { |child| child.clone } 
+1

बिल्कुल सही! यह है - अच्छा और संक्षिप्त। बहुत बहुत धन्यवाद। – Paul

0

ठीक है, यह वास्तव में एक प्रति नहीं है।

लेकिन आप

new_model.child_ids = template_model.child_ids 
3

यह कुछ जोड़े जहां/lib किया जा रहा है कर सकता है। उदाहरण के लिए clone_deep.rb।

module CloneDeep 
    def clone_deep 
    kopy = clone 
    self.class.reflect_on_all_associations.each do |association| 
     next if association.macro == :belongs_to 
     cloned_object = case association.macro 
         when :has_many 
          self.send(association.name).collect { |item| item.clone_deep } 
         when :has_one 
          self.send(association.name) && self.send(association.name).clone_deep 
         else 
          clone 
         end 
     kopy.send("#{association.name}=", cloned_object) 
    end 
    return kopy 
    end 
end 

कॉन्फ़िगर/प्रारंभकर्ता/फ़ोल्डर के तहत नया प्रारंभकर्ता बनाएं। इस फ़ाइल के अंदर

ActiveRecord::Base.send(:include, CloneDeep) 

अब आप इसके सभी_ऑन और होस_मनी एसोसिएशन के साथ मॉडल क्लोन करने में सक्षम हैं।

cloned_person = person.clone_deep 
cloned_person.save 
+0

केवल यह सरल समाधान मेरे लिए काम करता है .. दोनों अमीबा और गहरे_क्लोनेबल रत्न डिफ़ॉल्ट रूप से डुप्लिकेट करते थे और एसोसिएशन की प्रतिलिपि नहीं बनाते थे .. deep_cloneable मणि में असफल रहा है .. ड्रिल 4.1 धन्यवाद – Abs

1

#dup, #clone के बजाय इस्तेमाल किया जाना चाहिए के बाद से गुण उत्तरार्द्ध के मामले में कॉपी नहीं किए जाते।

module Promotion 
    class Banner 
    has_many :localizations 
    has_many :images 

    def deep_dup! 
     duplicate = dup 
     duplicate.save 

     duplicate.localizations = localizations.collect { |localization| localization.dup } 
     duplicate.images = images.collect { |image| image.dup } 

     duplicate 
    end 
    end 
end 

http://api.rubyonrails.org/classes/ActiveRecord/Core.html#method-i-dup

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