app/models/concerns/duplicable.rb
module Duplicable
extend ActiveSupport::Concern
def duplicate
instance = duplicate_instance
duplicate_localizations_for(instance)
instance
end
protected
def duplicate_instance
instance = self.dup
instance.save
instance
end
def duplicate_localizations_for(instance)
localizations.each do |l10n|
instance_l10n = l10n.dup
instance_l10n.about = instance
# note: fragile. It only works because every duplicate objects currently has a "title" property.
instance_l10n.title = I18n.t('copy_of', title: l10n.title)
instance_l10n.save
duplicate_featured_image(l10n, instance_l10n)
duplicate_blocks(l10n, instance_l10n)
end
end
def duplicate_featured_image(from, to)
return unless from.respond_to?(:featured_image) && from.featured_image.attached?
to.featured_image.attach(
io: URI.parse(from.featured_image.url).open,
filename: from.featured_image.filename.to_s,
content_type: from.featured_image.content_type
)
rescue
end
def duplicate_blocks(from, to)
return unless from.respond_to?(:contents)
from.blocks.ordered.each do |block|
duplicate_block(to, block)
end
end
def duplicate_block(instance, block)
duplicated_block = block.duplicate
duplicated_block.about = instance
duplicated_block.position = block.position
duplicated_block.save
end
end