我目前在 S3 上的解决方法(至少在 ActiveStorage 引入为has_one_attached
和has_many_attached
宏传递路径的选项之前)是实现move_to 方法。
所以我让 ActiveStorage 像现在通常那样(在存储桶的顶部)将图像保存到 S3,然后将文件移动到文件夹结构中。
该move_to
方法基本上将文件复制到您传递的文件夹结构中,然后删除放在存储桶根目录的文件。这样,您的文件就会到达您想要的位置。
因此,例如,如果我们要存储驱动程序详细信息:name
和drivers_license
,请将它们保存为您已经在执行的操作,以便它位于存储桶的顶部。
然后执行以下操作(我把我的放在一个助手中):
module DriversHelper
def restructure_attachment(driver_object, new_structure)
old_key = driver_object.image.key
begin
# Passing S3 Configs
config = YAML.load_file(Rails.root.join('config', 'storage.yml'))
s3 = Aws::S3::Resource.new(region: config['amazon']['region'],
credentials: Aws::Credentials.new(config['amazon']['access_key_id'], config['amazon']['secret_access_key']))
# Fetching the licence's Aws::S3::Object
old_obj = s3.bucket(config['amazon']['bucket']).object(old_key)
# Moving the license into the new folder structure
old_obj.move_to(bucket: config['amazon']['bucket'], key: "#{new_structure}")
update_blob_key(driver_object, new_structure)
rescue => ex
driver_helper_logger.error("Error restructuring license belonging to driver with id #{driver_object.id}: #{ex.full_message}")
end
end
private
# The new structure becomes the new ActiveStorage Blob key
def update_blob_key(driver_object, new_key)
blob = driver_object.image_attachment.blob
begin
blob.key = new_key
blob.save!
rescue => ex
driver_helper_logger.error("Error reassigning the new key to the blob object of the driver with id #{driver_object.id}: #{ex.full_message}")
end
end
def driver_helper_logger
@driver_helper_logger ||= Logger.new("#{Rails.root}/log/driver_helper.log")
end
end
更新 blob 键很重要,这样对键的引用就不会返回错误。
如果密钥没有更新,任何试图引用图像的函数都会在它以前的位置(在存储桶的顶部)而不是在它的新位置中查找它。
一旦文件被保存(即在创建操作中),我就会从我的控制器调用这个函数,这样即使不是,它看起来也是无缝的。
虽然这可能不是最好的方法,但它现在有效。
仅供参考:根据您给出的示例,new_structure
变量将是new_structure = "development/#{driver_object.image.key}"
.
我希望这有帮助!:)