2009-03-27 13 views
17

Czy istnieje sposób, aby skopiować stowarzyszenia jednego modelu do drugiego ...ActiveRecord: Czy mogę skopiować skojarzenia?

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

... takie, że mogę skopiować dzieci z szablonu do nowego modelu? (W rzeczywistości ten kod przenosi dzieci z szablonu do nowego modelu).

Wiem, że mogę zrobić to ręcznie, ale czy jest bardziej zwięzły?

Dzięki

Odpowiedz

25

Problemem jest to, że są klonowania szablon, ale nie jest to klonowanie dzieci. Wypróbuj coś takiego:

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

Perfect! To wszystko - ładnie i zwięźle. Dzięki wielkie. – Paul

0

Cóż, to naprawdę nie jest kopia.

Ale można zrobić

new_model.child_ids = template_model.child_ids 
3

Dodaj tę część, gdzie jest w/lib. Na przykład 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 

Utwórz nowy inicjator w folderze config/initializers /. Wewnątrz tego pliku wklej

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

Teraz możesz klonować model ze wszystkimi jego powiązaniami has_one i hos_many.

cloned_person = person.clone_deep 
cloned_person.save 
+0

Tylko to proste rozwiązanie zadziałało dla mnie .. zarówno amoeba, jak i deep_cloneable klejnoty domyślnie wywoływały dup, a nie kopiowały asocjacji .. deep_cloneable gem nie powiodło się ma wiele .............. Podziękowania – Abs

1

#dup powinien być stosowany zamiast #clone, ponieważ atrybuty nie są kopiowane w przypadku tego ostatniego.

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

Powiązane problemy