代码之家  ›  专栏  ›  技术社区  ›  sandre89

Rails ActiveStorage返回404即使存在严格的附件文件

  •  1
  • sandre89  · 技术社区  · 7 年前

    我有404台正在使用ActiveStorage。代码如下:

    class Model
      has_many_attached :attachments, dependent: :destroy
    
    # In form
    <%= form.file_field :attachments, multiple: true %>
    
    # In controller
    def model_request_params
      params.require(:model_name).permit(:title, attachments: [])
    end
    
    # In config/storage.yml
    local:
      service: Disk
      root: <%= Rails.root.join("storage") %>
    
    # In development.rb
    config.active_storage.service = :local
    
    # In view
    <%#= image_tag @model_instance.attachments.first %>
    

    当我打开浏览器时,生成的HTML如下: http://localhost:3000/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--3814080e8c7e26964c927840a18034d727c61d87/file.jpg ,但返回404未找到。

    奇怪的是,我有一个不同的Rails 5.2.0项目,一旦启动了这个项目,服务器控制台就会显示ActiveStorage::Blobs控制器正在进行的处理。

    然而,在这个项目中,我只看到:

    Started GET "/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--3814080e8c7e26964c927840a18034d727c61d87/file.jpg" for 127.0.0.1 at 2018-07-23 12:15:36 -0300

    后面不跟任何其他内容,不指示任何控制器或其他内容,但是浏览器会得到404,并且图像永远不会被加载。

    我可以确认附件已上载,因为 model_instance.attachments[0] 返回ActiveStorage::Attachment,但该文件也存在于我的项目的 storage/ 文件夹。

    系统配置

    Rails版本 :5.2.0(不是全新的,已更新-我在全新的Rails 5.2.0应用程序中没有看到此错误)

    Ruby版本 :2.3.6

    1 回复  |  直到 7 年前
        1
  •  0
  •   sandre89    7 年前

    罪魁祸首在我的routes.rb文件的开头就有:

    if Rails.env.development?
        scope format: true, constraints: { format: /jpg|png|gif|PNG/ } do
          get '/*anything', to: proc { [404, {}, ['']] }
        end
      end
    

    我完全忘记了这个黑客。这里有一些背景:

    我们经常将生产数据库转储到我们的开发机器上,以获得最新的开发环境。但是我们不会复制整个public/uploads文件夹,因为它太大了。

    这使得链接到上载资产的许多页面加载非常慢,因为每个映像都会命中dev应用程序服务器,该服务器出现404错误。

    在这几年的减速之后,我们在Makandra卡中发现了这一极好的解决方案:

    当您为开发加载转储时,记录可能引用图像 你的机器上没有。对这些图像的请求可能 在应用程序上结束,例如,如果定义了“全部捕获”路由, 导致控制器做一些重的提升。在有很多 缺少图像,这会减慢开发响应时间。你可以 通过定义这样的铁路路线来解决这个问题: (以上代码)

    图像(通常)直接从公共或资产提供服务,只要文件存在,就不会影响控制器/路由。如果文件丢失,请求将由上述路由处理,该路由立即以空的HTTP404响应进行响应。

    不用说,hacky fix劫持了activestorage使用的/rails路由,因为它们满足了约束条件。

    我不能对Makandra卡发表评论,但我希望谷歌能把人们带到这里。

    与此同时,我把黑客改为:

    if Rails.env.development?
        scope format: true, constraints: { format: /jpg|png|gif|PNG/ } do
          get '/*anything', to: proc { [404, {}, ['']] }, constraints: lambda { |request| !request.path_parameters[:anything].start_with?('rails/') }
        end
      end