Remove Paperclip and use just Active Storage
This commit is contained in:
@@ -1,98 +1,9 @@
|
||||
# This code is based on Thoughtbot's guide to migrating from Paperclip
|
||||
# to Active Storage:
|
||||
# https://github.com/thoughtbot/paperclip/blob/master/MIGRATING.md
|
||||
namespace :active_storage do
|
||||
desc "Copy paperclip's attachment database columns to active storage"
|
||||
task migrate_from_paperclip: :environment do
|
||||
logger = ApplicationLogger.new
|
||||
connection = ActiveRecord::Base.connection.raw_connection
|
||||
statement_name = "active_storage_statement"
|
||||
|
||||
unless connection.exec("SELECT COUNT(*) FROM pg_prepared_statements WHERE name='#{statement_name}'").each_row.to_a[0][0] > 0
|
||||
connection.prepare(statement_name, <<-SQL)
|
||||
with rows as(
|
||||
INSERT INTO active_storage_blobs (
|
||||
key, filename, content_type, metadata, byte_size, checksum, created_at
|
||||
) VALUES ($1, $2, $3, '{}', $4, $5, $6) RETURNING id
|
||||
)
|
||||
INSERT INTO active_storage_attachments (
|
||||
name, record_type, record_id, blob_id, created_at
|
||||
) VALUES ($7, $8, $9, (SELECT id FROM rows), $10)
|
||||
SQL
|
||||
end
|
||||
|
||||
Rails.application.eager_load!
|
||||
models = ActiveRecord::Base.descendants.reject(&:abstract_class?)
|
||||
paperclip_storage = Paperclip::Attachment.default_options[:storage]
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
models.each do |model|
|
||||
next if model.name == "OldPassword" && !model.table_exists?
|
||||
|
||||
attachments = model.column_names.map do |c|
|
||||
if c =~ /(.+)_file_name$/
|
||||
$1
|
||||
end
|
||||
end.compact
|
||||
|
||||
if attachments.blank?
|
||||
next
|
||||
end
|
||||
|
||||
model.find_each.each do |instance|
|
||||
attachments.each do |attachment|
|
||||
next if instance.send(:"storage_#{attachment}").attached?
|
||||
|
||||
source = if paperclip_storage == :filesystem
|
||||
instance.send(attachment).path
|
||||
else
|
||||
instance.send(attachment).url
|
||||
end
|
||||
|
||||
next if source.blank? || source == "/images/original/missing.png"
|
||||
|
||||
file = if paperclip_storage == :filesystem
|
||||
File.read(source) if File.exist?(source)
|
||||
else
|
||||
Net::HTTP.get(URI(source))
|
||||
end
|
||||
|
||||
connection.exec_prepared(
|
||||
statement_name, [
|
||||
SecureRandom.uuid, # Alternatively instance.send("#{attachment}_file_name"),
|
||||
instance.send("#{attachment}_file_name"),
|
||||
instance.send("#{attachment}_content_type"),
|
||||
instance.send("#{attachment}_file_size"),
|
||||
file && Digest::MD5.base64digest(file) || SecureRandom.hex(32),
|
||||
instance.updated_at.iso8601,
|
||||
"storage_#{attachment}",
|
||||
model.name,
|
||||
instance.id,
|
||||
instance.updated_at.iso8601
|
||||
])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ActiveStorage::Attachment.find_each do |attachment|
|
||||
blob = attachment.blob
|
||||
|
||||
next if blob.service.exist?(blob.key) || !attachment.record
|
||||
|
||||
name = attachment.name.delete_prefix("storage_")
|
||||
paperclip_attachment = attachment.record.send(name)
|
||||
|
||||
next unless paperclip_attachment.exists?
|
||||
|
||||
source_file = if paperclip_storage == :filesystem
|
||||
paperclip_attachment.path
|
||||
else
|
||||
URI.parse(paperclip_attachment.url).open.read
|
||||
end
|
||||
|
||||
logger.info "Copying #{paperclip_attachment.url} to active storage"
|
||||
blob.service.upload(blob.key, source_file)
|
||||
end
|
||||
desc "Updates ActiveStorage::Attachment old records created when we were also using paperclip"
|
||||
task remove_paperclip_compatibility_in_existing_attachments: :environment do
|
||||
ApplicationLogger.new.info "Updating Active Storage attachment records"
|
||||
ActiveStorage::Attachment.where("name ILIKE 'storage_%'")
|
||||
.where.not(record_type: "Ckeditor::Asset")
|
||||
.update_all("name = replace(name, 'storage_', '')")
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user