如何向 ActiveStorage 添加自定义服务

How to add a custom service to ActiveStorage

我想向 ActiveStorage 添加自定义服务,因为我想覆盖 ActiveStorage::Service::S3Service 服务的 url 方法,这样我就可以在我的 S3 存储桶前面使用 CloudFront CDN。我想我不需要 presigned_url 参数,我只需要密钥,因为 CloudFront 实例将具有对 S3 存储桶的完全读取权限。

在子class是ActiveStorage::Service::S3ServiceActiveStorage::Service命名空间中添加一个class。覆盖您要覆盖的方法。例如:

# lib/active_storage/service/cloudfront_s3_service.rb 
require "active_storage/service/s3_service"

class ActiveStorage::Service::CloudfrontS3Service < ActiveStorage::Service::S3Service
  def url(key, **)
    # ...
  end
end

参考config/storage.yml中的自定义服务:

production:
  service: CloudfrontS3
  access_key_id: ""
  secret_access_key: ""
  region: ""
  bucket: ""

对于任何感兴趣的人,我有一个类似的问题,我想使用 S3Service 使用的相同的平面单桶存储。一旦你知道如何,它就足够简单了:

require "active_storage/service/disk_service"

# S3 uses a flat folder structure, so mimic that so we an sync files and databases
module ActiveStorage
  class Service
    class FlatDiskService < DiskService
      private

      def folder_for(_key)
        "/"
      end
    end
  end
end

配置如下:

local:
   service: FlatDisk
   root: <%= Rails.root.join("storage") %>

编辑:我已经使用适用于 Rails 6.

的修正版本更新了答案