Ответ 1
Проблема в том, что вы клонируете шаблон, но не клонируете его детям. Попробуйте что-то вроде:
template_model = MyModel.find(id)
new_model = template_model.clone
new_model.children << template_model.children.collect { |child| child.clone }
Есть ли способ скопировать ассоциации одной модели в другую...
template_model = MyModel.find(id)
new_model = template_model.clone
new_model.children << template_model.children # I want to *copy* children
... такое, что я копирую детей из шаблона в новую модель? (На самом деле этот код перемещает детей из шаблона в новую модель).
Я знаю, что я могу это сделать вручную, но есть ли более краткий путь?
Спасибо
Проблема в том, что вы клонируете шаблон, но не клонируете его детям. Попробуйте что-то вроде:
template_model = MyModel.find(id)
new_model = template_model.clone
new_model.children << template_model.children.collect { |child| child.clone }
Добавьте это, где находится под /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
Создайте новый инициализатор в папке config/initializers/. Внутри этого файла вставьте
ActiveRecord::Base.send(:include, CloneDeep)
Теперь вы можете клонировать модель со всеми ее has_one и ассоциациями hos_many.
cloned_person = person.clone_deep
cloned_person.save
#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-clone http://api.rubyonrails.org/classes/ActiveRecord/Core.html#method-i-dup
Ну, это не совсем копия.
Но вы могли бы сделать
new_model.child_ids = template_model.child_ids