You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

60 lines
1.8 KiB

namespace :nodes do
desc "Deep copy a node including descendants and attachments. Usage: rake nodes:copy[22]"
task :copy, [ :node_id ] => :environment do |t, args|
node_id = args[:node_id] || 22
begin
source = Node.find(node_id)
puts "Starting deep copy of Node #{source.id}: \"#{source.title}\"..."
# We wrap in a transaction to ensure integrity
new_root = Node.transaction do
copy_node_recursively(source)
end
puts "Successfully created deep copy!"
puts "Source ID: #{source.id}"
puts "New ID: #{new_root.id}"
rescue ActiveRecord::RecordNotFound
puts "Error: Node with ID #{node_id} not found."
rescue => e
puts "Error during copy: #{e.message}"
puts e.backtrace.first(5)
end
end
def copy_node_recursively(source, parent = nil)
# 1. Duplicate the node (this copies attributes including JSONB translations)
new_node = source.dup
# 2. Set parent (Ancestry gem handles the tree logic)
# If no parent provided, we default to the same parent as the source (sibling)
new_node.parent = parent || source.parent
# 3. Modify title of the root copy to distinguish it
if parent.nil?
I18n.available_locales.each do |locale|
title = source.title(locale: locale)
if title.present?
new_node.send(:title=, "#{title} (Copy)", locale: locale)
end
end
end
# 4. Save to get an ID
new_node.save!
# 5. Duplicate Attachments
source.attachments.each do |attachment|
new_attachment = attachment.dup
new_attachment.attachable_for = new_node
new_attachment.save!
end
# 6. Recurse for children
source.children.ordered.each do |child|
copy_node_recursively(child, new_node)
end
new_node
end
end