关闭ActiveStorage公共URL后如何获取附件URL?
解决方案
当关闭config.active_storage.draw_routes = false后,ActiveStorage的公共路由被禁用,无法通过url方法生成可访问的公共链接,此时应该通过控制器直接发送文件内容,而非重定向。以下是具体实现步骤:
1. 保留ActiveStorage配置
确保config/application.rb(或对应环境配置文件,如config/environments/production.rb)中已添加:
config.active_storage.draw_routes = false
2. 修改InvoicesController的show方法
放弃redirect_to,改用send_data直接向客户端发送文件内容,同时加入权限验证逻辑:
class InvoicesController < ApplicationController # 示例:用户登录验证(根据你的权限体系调整) before_action :authenticate_user! before_action :set_invoice before_action :validate_invoice_access def show # 检查发票是否已附加PDF unless @invoice.generated_pdf.attached? redirect_to invoices_path, alert: "该发票无可用PDF文件" return end blob = @invoice.generated_pdf.blob # 发送文件,disposition设为'attachment'触发下载,'inline'则在浏览器打开 send_data blob.download, filename: blob.filename, type: blob.content_type, disposition: "attachment" end private def set_invoice @invoice = Invoice.find(params[:id]) end # 自定义权限验证逻辑(示例:仅发票所属用户可访问) def validate_invoice_access unless @invoice.user_id == current_user.id redirect_to root_path, alert: "无该发票的访问权限" end end end
问题原因说明
- 关闭
draw_routes后,ActiveStorage的内置路由(如rails/active_storage/disk/*)被移除,@invoice.generated_pdf.url生成的路径没有对应的路由处理,导致报错。 ActiveStorage::SetCurrent主要用于生成临时签名URL(适用于云存储服务如S3),但Disk服务在关闭公共访问后无法通过该方式生成有效URL,因此直接发送文件内容是更适合的方案。
内容的提问来源于stack exchange,提问作者Ricky883249
相关产品推荐
相关产品推荐

