Files
openfoodnetwork/app/models/concerns/has_migrating_file.rb
Maikel Linke 1c1f9d73a3 Add task to migrate existing files to Active Storage
Common migrations look for all models with *_file_name attributes but I
found that unreliable in our code base. It finds too many model classes
and doesn't allow us to be more selective in the migration. So I used
our own migration declaration to migrate exactly those attachments
specified.
2022-04-25 13:00:31 +10:00

68 lines
1.7 KiB
Ruby

# frozen_string_literal: true
module HasMigratingFile
extend ActiveSupport::Concern
@migrating_models = []
def self.migrating_models
@migrating_models
end
included do
HasMigratingFile.migrating_models.push(name)
end
class_methods do
def has_one_migrating(name, paperclip_options = {})
# Active Storage declaration
has_one_attached name
# Backup Active Storage methods before they get overridden by Paperclip.
alias_method "active_storage_#{name}", name
alias_method "active_storage_#{name}=", "#{name}="
# Paperclip declaration
#
# This will define the `name` and `name=` methods as well.
has_attached_file name, paperclip_options
# Paperclip callback to duplicate file with Active Storage
#
# We store files with Paperclip *and* Active Storage while we migrate
# old Paperclip files to Active Storage. This enables availability
# during the migration.
public_send("after_#{name}_post_process") do
path = processed_local_file_path(name)
if public_send(name).errors.blank? && path.present?
attach_file(name, File.open(path))
end
end
end
end
def attach_file(name, io)
attachable = {
io: io,
filename: public_send("#{name}_file_name"),
content_type: public_send("#{name}_content_type"),
identify: false,
}
public_send("active_storage_#{name}=", attachable)
end
private
def processed_local_file_path(name)
attachment = public_send(name)
temporary = attachment.queued_for_write[:original]
if temporary&.path.present?
temporary.path
else
attachment.path
end
end
end