Skip to content

Instantly share code, notes, and snippets.

@owen2345
Last active March 10, 2024 16:11
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 owen2345/33730a452d73b6b292326bb602b0ee6b to your computer and use it in GitHub Desktop.
Save owen2345/33730a452d73b6b292326bb602b0ee6b to your computer and use it in GitHub Desktop.
activestorage rename already uploaded files (Rails rename activestorage) Local and AWS storage support
# frozen_string_literal: true
module Storage
class RemoteFileRenamer < ApplicationService
attr_reader :file_blob, :new_name, :file
# @param file [ActiveStorage::File]
# @param new_name [String]
# @param variation [Symbol] Sample: :thumbnail
def initialize(file, new_name, variation = nil)
@file = file
@file_blob = variation ? find_variation_blob(file, variation) : file.blob
@new_name = new_name
end
def call
log('file-blob not found', mode: :error) && return unless file_blob
file_blob.service.name == :amazon ? rename_aws_file : rename_local_file
file_blob.update!(key: new_name, filename: new_name)
file.reload
end
private
def rename_aws_file
obj = file_blob.service.send(:object_for, file_blob.key)
obj.move_to(bucket: obj.bucket.name, key: new_name)
end
def rename_local_file
old_path = file_blob.service.path_for(file_blob.key)
new_path = file_blob.service.path_for(new_name)
Dir.exist?(File.dirname(new_path)) || FileUtils.mkdir_p(File.dirname(new_path))
FileUtils.mv(old_path, new_path) if File.exist?(old_path)
end
def find_variation_blob(file, variation)
variant = file.variant(variation)
variant.process unless variant.processed?
variant.image
end
end
end
# frozen_string_literal: true
class User < ApplicationRecord
has_one_attached :photo do |attachable|
attachable.variant :thumb, resize_to_fill: [100, nil]
end
after_create_commit :rename_remote_photo, prepend: true, on: :create, if: :file_blob
after_update_commit :rename_remote_photo, prepend: true, if: -> { saved_changes_to_name? && photo.blob }
def remote_photo_filename
"#{name}#{File.extname(photo.blob.filename.to_s)}"
end
def remote_thumb_filename
"#{name}-thumb#{File.extname(photo.blob.filename.to_s)}"
end
private
def rename_remote_photo
new_name = remote_photo_filename
RemoteFileRenamer.new(file, new_name).call
rename_thumbnail
end
def rename_thumbnail
new_name = remote_thumb_filename
RemoteFileRenamer.new(file, new_name, :thumb).call
end
end
@owen2345
Copy link
Author

owen2345 commented May 6, 2022

Thinking to make it part of activestorage-delayed gem by default.

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