Skip to content

Instantly share code, notes, and snippets.

@brianjlandau
Last active July 5, 2018 08:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save brianjlandau/3bf4e0e056e370517152 to your computer and use it in GitHub Desktop.
Save brianjlandau/3bf4e0e056e370517152 to your computer and use it in GitHub Desktop.
This allows you to migrate files on S3 stored by paperclip to a new location.
# Example usage:
#
# PaperclipS3Migrator.new(
# [User, BlogPost, Page],
# ':attachment/:id/:style/:filename',
# ':class/:id/:attachment/:style/:updated_at_:filename'
# ).migrate
#
class PaperclipS3Migrator < Struct.new(:klasses, :old_path, :new_path)
def migrate
klasses.each do |klass|
KlassMigrator.new(klass, old_path, new_path).migrate
end
end
private
class KlassMigrator < Struct.new(:klass, :old_path, :new_path)
def migrate
model_scope.find_each do |record|
attachments_for_klass.each do |attachment_name|
if record.send("#{attachment_name}?")
migrate_attachment(record.send(attachment_name))
end
end
end
end
private
def model_scope
klass.unscoped.where(conditions)
end
def conditions
attachments_for_klass.map {|attachment_name|
"#{attachment_name}_file_name IS NOT NULL"
}.join(' OR ')
end
def attachments_for_klass
@attachments_for_klass ||= Paperclip::AttachmentRegistry.names_for(klass)
end
def migrate_attachment(attachment)
attachment.styles.keys.push(:original).each do |style|
StyleMigrator.new(attachment, style, old_path, new_path).migrate
end
end
end
class StyleMigrator < Struct.new(:attachment, :style, :old_path, :new_path)
def migrate
old_object.copy_to(new_key, {:acl => :public_read})
rescue => exception
puts "[PaperclipS3Migrator][#{attachment.instance.class.name}:#{attachment.instance.id}:#{attachment.name}:#{style}] #{exception.inspect}"
end
private
def old_key
attachment.send(:interpolate, old_path, style)
end
def new_key
attachment.send(:interpolate, new_path, style)
end
def old_object
bucket.objects[old_key]
end
def bucket
s3_client.buckets[s3_credentials[:bucket]]
end
def s3_client
@s3_client ||= AWS::S3.new(s3_credentials.except(:bucket))
end
def s3_credentials
Paperclip::Attachment.default_options[:s3_credentials]
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment