Skip to content

Instantly share code, notes, and snippets.

@colinpetruno
Last active September 28, 2018 19:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save colinpetruno/037de4fafa4cff695b1d7905cd6fd7c2 to your computer and use it in GitHub Desktop.
Save colinpetruno/037de4fafa4cff695b1d7905cd6fd7c2 to your computer and use it in GitHub Desktop.
Postgres Paperclip to ActiveStorage Rake Task
namespace :backfill do
task active_storage: :environment do
require 'open-uri'
def key(instance, attachment)
SecureRandom.uuid
# Alternatively:
# instance.send("#{attachment}_file_name")
end
def checksum(attachment)
# local files stored on disk:
url = attachment.path
begin
Digest::MD5.base64digest(File.read(url))
rescue StandardError
"fakechecksum"
end
# remote files stored on another person's computer:
# url = attachment.url
# Digest::MD5.base64digest(Net::HTTP.get(URI(url)))
end
### START SCRIPT
# postgres
get_blob_id = 'LASTVAL()'
connection = ActiveRecord::Base.connection.raw_connection
active_storage_blob_statement = connection.prepare('active_storage_blob_statement', <<-SQL)
INSERT INTO active_storage_blobs (
"key", filename, content_type, metadata, byte_size, checksum, created_at
) VALUES ($1, $2, $3, '{}', $4, $5, $6)
SQL
active_storage_attachment_statement = connection.prepare('active_storage_attachment_statement', <<-SQL)
INSERT INTO active_storage_attachments (
name, record_type, record_id, blob_id, created_at
) VALUES ($1, $2, $3, #{get_blob_id}, $4)
SQL
# models = [ Payment, User, etc]
Rails.application.eager_load!
models = ActiveRecord::Base.descendants.reject(&:abstract_class?)
ActiveRecord::Base.transaction do
models.each do |model|
attachments = model.column_names.map do |c|
if c =~ /(.+)_file_name$/
$1
end
end.compact
next if attachments.blank?
model.find_each.each do |instance|
attachments.each do |attachment|
next if instance.send(attachment).path.blank?
connection.exec_prepared(
'active_storage_blob_statement',
[
key(instance, attachment),
instance.send("#{attachment}_file_name"),
instance.send("#{attachment}_content_type"),
instance.send("#{attachment}_file_size"),
checksum(instance.send(attachment)),
instance.updated_at.iso8601
]
)
connection.exec_prepared(
'active_storage_attachment_statement',
[
attachment,
model.name,
instance.id,
instance.updated_at.iso8601
]
)
end
end
end
end
#active_storage_attachment_statement.close
#active_storage_blob_statement.close
end
end
@mike-burns
Copy link

Thanks for this; I've turned it into a PR: thoughtbot/paperclip#2613 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment