有没有办法在下载时更改/设置文件名?
示例:Jon Smith上传了他的头像,文件名为4321431-small.jpg
。在下载时,我想将文件重命名为jon_smith__headshot.jpg
。
查看:
<%= url_for user.headshot_file %>
此url_for
从Amazon S3下载文件,但使用原始文件名。
我有什么选择?
答案 0 :(得分:4)
内置控制器为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
文件名。
答案 1 :(得分:1)
我知道已经回答了这个问题,但是我想添加第二种方法。保存用户对象时,您可以更新文件名。使用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
答案 2 :(得分:1)
@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
,而不能提供文件名。
如果您在ActiveStorage存储库中看到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
,当您查看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
,仅此而已。
答案 3 :(得分:0)