首页 > 解决方案 > 活动存储 - 多种服务 - 直接上传无法按预期工作

问题描述

我在storage.yml

amazon:
  service: S3
  bucket: bucket1
  region: eu-central-1
  access_key_id: 321
  secret_access_key: 321

unsafe_files:
  service: S3
  bucket: unsafe-files
  region: eu-central-1
  access_key_id: 123
  secret_access_key: 123

我将亚马逊服务用于某些文件,我想将该unsafe_files服务用于其他文件,以便我可以将其放入另一个s3存储桶中。

使用该unsafe_files服务的模型如下所示(非常简单):

class Customer < ActiveRecord::Base
  belongs_to :customer_image
end
class CustomerImage < Image
  has_one_attached :file, service: Rails.configuration.settings[:unsafe_files_service]
end

Rails.configuration.settings[:unsafe_files_service]只是unsafe_files

application.rb在我正在设置的rails中

config.active_storage.service = :amazon因此默认情况下它使用amazon定义的服务storage.yml

现在我想使用 直接上传文件form_with,这也很简单:

<%= form_with model: [@customer, CustomerImage.new] do |form| %>
  <%=
    form.file_field :file,
                    accept: 'image/jpeg',
                    direct_upload: true,
                    multipart: true
  %>
  <%= form.submit "submit" %>
<% end %>

现在我知道(或者我想我知道)在使用active_storage. 一些javascript监听on form提交事件,首先将其中的内容file_field发送给DirectUploadsController检查图像,生成直接上传url,然后我们直接将文件上传到指定的服务。都在这里:https ://github.com/rails/rails/blob/6ecf1065da57360bdc9f1d85e2c2d9314dcb79e0/activestorage/app/controllers/active_storage/direct_uploads_controller.rb#L14

该服务使用文件密钥或 ID 进行响应。之后表单提交继续,我们保存我们收到的id,这就是文件之间的关系。

但是当我们点击DirectUploadsController并创建 blob 时,它会获得默认的 service_name(参见:https ://github.com/rails/rails/blob/6ecf1065da57360bdc9f1d85e2c2d9314dcb79e0/activestorage/app/models/active_storage/blob.rb#L115 )

长话短说,当使用直接上传时,我无法选择服务,我必须依赖 Rails 默认服务。

有解决方法吗?或者也许我错过了什么?

标签: ruby-on-railsrubyruby-on-rails-6rails-activestorage

解决方案


如果您想给create_before_direct_upload!自己打电话(以便您可以指定 service_name),那么我认为您必须DirectUploadsController以某种方式覆盖。您可以编写自己的控制器,或者(高级)尝试重新打开和修补DirectUploadsController. 我的应用程序是前者。

来自 OP 的更新:

我最终重新打开了 DirectUploadsController (并且还在表单 file_field 中添加了一个选项以传递自定义的 direct_upload_url 它工作得很好,尽管我不喜欢我不得不与内部组件打成一片。我已经检查了 active_storage gem,看起来那将不得不添加此功能,因为当前的实现没有解决方法。 – beniutek


推荐阅读