有没有办法在下载时更改/设置文件名?
示例:Jon Smith 上传了他的头像,文件名为4321431-small.jpg
. 在下载时,我想将文件重命名为jon_smith__headshot.jpg
.
看法:
<%= url_for user.headshot_file %>
这url_for
将从 Amazon S3 下载文件,但使用原始文件名。
我在这里有什么选择?
有没有办法在下载时更改/设置文件名?
示例:Jon Smith 上传了他的头像,文件名为4321431-small.jpg
. 在下载时,我想将文件重命名为jon_smith__headshot.jpg
.
看法:
<%= url_for user.headshot_file %>
这url_for
将从 Amazon S3 下载文件,但使用原始文件名。
我在这里有什么选择?
内置控制器为 blob 提供存储的文件名。您可以实现一个自定义控制器,为它们提供不同的文件名:
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
从 5.2.0 RC2 开始,您不需要传递ActiveStorage::Filename
; String
您可以改为传递文件名。
我知道这已经得到解答,但我想添加第二种方法。您可以在保存用户对象时更新文件名。使用 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
@GuilPejon 的方法将起作用。直接调用的问题service_url
是:
disk
如果服务处于开发模式,它将不起作用。它不适用于磁盘服务的原因是磁盘服务需要ActiveStorage::Current.host
存在才能生成 URL。ActiveStorage::Current.host
并被设置为,所以当被调用app/controllers/active_storage/base_controller.rb
时它会丢失。service_url
到目前为止,ActiveStorage 提供了另一种访问附件 URL 的方法:
rails_blob_(url|path)
(推荐方式)但是如果你使用它,你只能提供content-disposition
而不是文件名。
如果您config/routes.rb
在 `ActiveStorage 存储库中看到,您将找到以下代码。
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
当您查看时,blobs_controller
您会发现以下代码:
def show
expires_in ActiveStorage::Blob.service.url_expires_in
redirect_to @blob.service_url(disposition: params[:disposition])
end
所以很明显,rails_blob_(url|path)
你只能通过disposition
,仅此而已。