0

i have an issue in trying to clone an object that has nested elements. I know how to completely clone it, but i want to clone only some of the children elements on each nesting level.

So lets say i have structure like this,im making by example names (its not actual case)

class Town < ActiveRecord::Base
 has_many :districts
 has_many :buildings, through: :districts

class District < ActiveRecord::Base
 belongs_to :town
 has_many :buildings

class Building < ActiveRecord::Base
 belongs_to :district
 has_many :rooms
 has_many :toilets

 #and i have of course rooms and toilets with belongs_to relation to Building

So basicaly if i want to clone entire existing Town object i would just do something like

Town.last.clone

But i want to do something like this instead. I want to dup existing Town, and then recreate only some of the children objects, based on collections i have. So if town has 10 districts, i want to dup only one of them, or more of them (based on collections i have), and then district has 100 houses, i will again dup only the ones i need and so on untill rooms and toilets. So i tryed with something like this.

#now i have these collections, i get them in some fashion, and they belong to Town(1) below    
districts = District.find(1,2,3) #those ids are belonging to Town
buildings = Building.find(1,2,3) #those ids are belonging to districts above
rooms = Room.find(1,2,3,4,5,6) # and are belonging to some of buildings above
toilets = Toilet.find(1,2,3,4,5,6,7) #and are belonging to some of buildings

#so now i want to do this
old_town = Town.find(1)
new_town = old_town.dup.tap

districts.each od |district|
  new_town.districts << district.dup
end
#and i get all the districts to new created town but when i try further in nesting it wont work, like this

districts.each od |district|
  new_town.districts << district.dup

  buildings.each do |building|
    district.buildings << building.dup
  end
end

#and so on inside it for toilets and rooms it just wont work, like it doesnt attach them to new_town. What am i doing wrong?

So i just want selective dup/clone of filtered elements belonging to parent. And each other to respect their relations.

Thanks allot.

Tester
  • 3
  • 1
  • Do you want to put the building's duplication into a district that belongs to the new town? If so, this: `district.buildings << building.dup` should be changed, so the receiver of `#buildings` is the duplicated district. Btw. These ::find methods are really messy. – Adam Zapaśnik Mar 23 '17 at 18:07
  • Hi, yes i am trying to add buildings duplications so it gets attached to district duplication i created. How can i achieve that?Now im bit confused, i know what you are saying, but dont know how to achieve that in same loop. And for toilets and rooms, i do it in same manner right? – Tester Mar 23 '17 at 19:34

1 Answers1

0
districts.each do |district|
  district_dup = district.dup
  buildings.each do |building|
    district_dup.buildings << building.dup
  end
  new_town.districts << district_dup
end

Could you try something like that? If you want to add rooms and toilets, you will need to create building_dup just like district_dup.

Edit: Cleaner version

districts.map(&:dup).each do |dis| #creates an Array of duplications and iterates through elements
  dis.buildings = buildings.map(&:dup).each do |building| #creates an Array of duplications which is later added to dis.buildings
    building.rooms = rooms.map(&:dup)
    building.toilets = toilet.map(&:dup)
  end
end

If dis.buildings = buildings.map(&:dup).each fails, please try to change #= to #concat in all cases.

Adam Zapaśnik
  • 633
  • 4
  • 9
  • Ill try it tomorrow but i think that is the issue. You have the point. Im stupid -.- And i was wondering why its not attaching them... Ill mark its as correct answer since it is 99% – Tester Mar 23 '17 at 20:25