[英]Rails + ActiveStorage on S3: Set filename on download?
Is there a way to change/set the filename on download? 有没有办法在下载时更改/设置文件名?
Example: Jon Smith uploaded his headshot, and the filename is 4321431-small.jpg
. 示例:Jon Smith上传了他的头像,文件名为
4321431-small.jpg
。 On download, I'd like to rename the file to jon_smith__headshot.jpg
. 在下载时,我想将文件重命名为
jon_smith__headshot.jpg
。
View: <%= url_for user.headshot_file %>
查看:
<%= url_for user.headshot_file %>
This url_for
downloads the file from Amazon S3, but with the original filename. 此
url_for
从Amazon S3下载文件,但使用原始文件名。
What are my options here? 我有什么选择?
The built-in controller serves blobs with their stored filenames. 内置控制器为blob提供存储的文件名。 You can implement a custom controller that serves them with a different filename:
您可以使用不同的文件名实现自定义控制器:
class HeadshotsController < ApplicationController
before_action :set_user
def show
redirect_to @user.headshot.service_url(filename: filename)
end
private
def set_user
@user = User.find(params[:user_id])
end
def filename
ActiveStorage::Filename.new("#{user.name.parameterize(separator: "_")}__headshot#{user.headshot.filename.extension_with_delimiter}")
end
end
Starting with 5.2.0 RC2, you won't need to pass an ActiveStorage::Filename
; 从5.2.0 RC2开始,您不需要传递
ActiveStorage::Filename
; you can pass a String
filename instead. 你可以传递一个
String
文件名。
The approach of @GuilPejon will work. @GuilPejon的方法将起作用。 The problem with directly calling the
service_url
is: 直接调用
service_url
的问题是:
disk
in development mode. disk
,它将无法工作。 The reason it does not work for disk service is that disk service requires ActiveStorage::Current.host
to be present for generating the URL. 它不适用于磁盘服务的原因是磁盘服务需要
ActiveStorage::Current.host
才能生成URL。 And ActiveStorage::Current.host
gets set in app/controllers/active_storage/base_controller.rb
, so it will be missing when service_url
gets called. 并且在
app/controllers/active_storage/base_controller.rb
设置了ActiveStorage::Current.host
,因此在调用service_url
时它将丢失。
ActiveStorage as of now gives one more way of accessing the URL of the attachments: ActiveStorage到目前为止提供了另一种访问附件URL的方法:
rails_blob_(url|path)
(recommended way) rails_blob_(url|path)
(推荐方式) But if you use this, you can only provide content-disposition
and not the filename. 但是如果你使用它,你只能提供
content-disposition
而不是文件名。
If you see the config/routes.rb
in the `ActiveStorage repo you will find the below code. 如果你在`ActiveStorage repo中看到
config/routes.rb
,你会发现下面的代码。
get "/rails/active_storage/blobs/:signed_id/*filename" => "active_storage/blobs#show", as: :rails_service_blob
direct :rails_blob do |blob, options|
route_for(:rails_service_blob, blob.signed_id, blob.filename, options)
end
and when you look into blobs_controller
you will find the below code: 当你研究
blobs_controller
你会发现以下代码:
def show
expires_in ActiveStorage::Blob.service.url_expires_in
redirect_to @blob.service_url(disposition: params[:disposition])
end
So it is clear that in rails_blob_(url|path)
you can only pass disposition
and nothing more. 所以很明显,在
rails_blob_(url|path)
你只能传递disposition
而已。
I know this was already answered, but I would like to add a second way of doing this. 我知道这已经回答了,但我想补充第二种做法。 You could update your file name when the user object is saved.
保存用户对象时,可以更新文件名。 Using OP's example of the
user
model and the headshot_file
field, this is how you could solve this: 使用OP的
user
模型示例和headshot_file
字段,您可以通过以下方式解决此问题:
# app/models/user.rb
after_save :set_filename
def set_filename
file.blob.update(filename: "ANYTHING_YOU_WANT.#{file.filename.extension}") if file.attached?
end
I haven't played with ActiveStorage yet, so this is kind of a shot in the dark. 我还没有玩过ActiveStorage,所以这是一个黑暗中的镜头。
Looking at the ActiveStorage source for the S3 service, it looks like you can specify the filename and disposition for the upload. 查看S3服务的ActiveStorage 源 ,看起来您可以指定上载的文件名和处置方式。 From the guides it seems that you can use
rails_blob_path
to access the raw URL of the upload and pass these parameters. 从指南中可以看出,您可以使用
rails_blob_path
访问上载的原始URL并传递这些参数。 Therefor you might try: 因此你可以尝试:
rails_blob_url(user.headshot_file, filename: "jon_smith__headshot.jpg"`enter code here`)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.