You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关闭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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 10:52:38